Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement tool selection logic based on the policy #90

Merged
merged 13 commits into from
Sep 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 9 additions & 8 deletions packages/packages.json
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
{
"dev": {
"skill/valory/market_manager_abci/0.1.0": "bafybeicjqkzen2gvpnc3syojcf6ibr4kjaorcwktikqp2zzxec6vs64oky",
"skill/valory/decision_maker_abci/0.1.0": "bafybeic77zhxf5a53ngfzacklmm3nag4t4jeufdhoeg3ykrmvknojtwipi",
"skill/valory/trader_abci/0.1.0": "bafybeibi3rt3rdk4bvng3tlmwdxal3mk3bflq4cgq3fxyjwzpmhj3y6pmy",
"skill/valory/market_manager_abci/0.1.0": "bafybeigvw5tqei5xb272jb7retxiryhuhxxzupddmbdixgsmxzco3n2dde",
"skill/valory/decision_maker_abci/0.1.0": "bafybeihm77vt53vu3xt6x7istsvaw75juptlynpriebgeltbil5evvhtue",
"skill/valory/trader_abci/0.1.0": "bafybeiea2r67bzi5gkymu2pu2m3sg3lflke5m2finonak4uprqpbdcp2ru",
"contract/valory/market_maker/0.1.0": "bafybeif6hivvhxqv4a3uqo2v3yszluzrmngsp624utdi466xwo5qbz5bsi",
"agent/valory/trader/0.1.0": "bafybeigoojaxpc7sz7vuswkxvpa5lp37lipuwc4qycztqk4hxdesmxqcda",
"service/valory/trader/0.1.0": "bafybeidyuzdmwrt66w32oppopviesvhinmwd76q73zv3dex2th7nldpbyi",
"agent/valory/trader/0.1.0": "bafybeiba5eqawktwkpziiazxm5u6ftm7o3zytcbafqsjwt7zrr63o2yis4",
"service/valory/trader/0.1.0": "bafybeifqi4yprf6ajureyqn45aa3mo7vezwsx63skc4n56grlormdzoz5i",
"contract/valory/erc20/0.1.0": "bafybeiggo4u56drxusvcdruqrr7mlfzqbieg4hajalh4tkctxhh3c5lpdi",
"skill/valory/tx_settlement_multiplexer_abci/0.1.0": "bafybeidtrigrfjikl7tkbtowbp6mrdzxulayxnxcmviwy3gag557vnymlq",
"contract/valory/mech/0.1.0": "bafybeibfikekaruskx6ui7u4qnls57i2namfxi45zhqslziqyxg4npjzxu",
"skill/valory/tx_settlement_multiplexer_abci/0.1.0": "bafybeiey57caacd6d3ow25i6a2zuiinkx6kjtckdktannk7kijpd3p2zb4",
"contract/valory/mech/0.1.0": "bafybeidtezc4ubsyqdltiojvqe5eeh77ejte7vqbojspiej5quivgap3ae",
"contract/valory/realitio/0.1.0": "bafybeigb722aznqhc5lsbt3dn4bpyaqe5hnl5onmnestqmzliwtvl3eaom",
"contract/valory/realitio_proxy/0.1.0": "bafybeibvndq6756qck7forgeavhdbn6ykgqs2ufyg7n5g6qdfpveatxuwy",
"contract/valory/conditional_tokens/0.1.0": "bafybeicxwjdbmjajgr5rsmadtkxxwmcm42r2htef3tvng73uzib4hmb6qa"
"contract/valory/conditional_tokens/0.1.0": "bafybeicxwjdbmjajgr5rsmadtkxxwmcm42r2htef3tvng73uzib4hmb6qa",
"contract/valory/agent_registry/0.1.0": "bafybeib6odummk6qqietjekpljkmhqfxk7kv56kv6pyfsnnanews625ncy"
},
"third_party": {
"protocol/open_aea/signing/1.0.0": "bafybeifuxs7gdg2okbn7uofymenjlmnih2wxwkym44lsgwmklgwuckxm2m",
Expand Down
17 changes: 9 additions & 8 deletions packages/valory/agents/trader/aea-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ contracts:
- valory/market_maker:0.1.0:bafybeif6hivvhxqv4a3uqo2v3yszluzrmngsp624utdi466xwo5qbz5bsi
- valory/erc20:0.1.0:bafybeiggo4u56drxusvcdruqrr7mlfzqbieg4hajalh4tkctxhh3c5lpdi
- valory/multisend:0.1.0:bafybeidfktuprydtmi4umolfles5qaf7s3t26puvvs44hvkq6uwwr3ia3a
- valory/mech:0.1.0:bafybeibfikekaruskx6ui7u4qnls57i2namfxi45zhqslziqyxg4npjzxu
- valory/mech:0.1.0:bafybeidtezc4ubsyqdltiojvqe5eeh77ejte7vqbojspiej5quivgap3ae
- valory/conditional_tokens:0.1.0:bafybeicxwjdbmjajgr5rsmadtkxxwmcm42r2htef3tvng73uzib4hmb6qa
- valory/realitio:0.1.0:bafybeigb722aznqhc5lsbt3dn4bpyaqe5hnl5onmnestqmzliwtvl3eaom
- valory/realitio_proxy:0.1.0:bafybeibvndq6756qck7forgeavhdbn6ykgqs2ufyg7n5g6qdfpveatxuwy
Expand All @@ -41,10 +41,10 @@ skills:
- valory/reset_pause_abci:0.1.0:bafybeiblayblhp5wuirfomwcpgydg35ve5tfq3xxetlosjn47wva5ucmzy
- valory/termination_abci:0.1.0:bafybeieqfhvk6klnvxak3vo2ibslkrnnk2bfsn5l3gbaelcprd6cjngxki
- valory/transaction_settlement_abci:0.1.0:bafybeicisazpyvnnzlqso3txiucxr5qhsa4ac7ius6b4mhouxr2wkadwfy
- valory/tx_settlement_multiplexer_abci:0.1.0:bafybeidtrigrfjikl7tkbtowbp6mrdzxulayxnxcmviwy3gag557vnymlq
- valory/market_manager_abci:0.1.0:bafybeicjqkzen2gvpnc3syojcf6ibr4kjaorcwktikqp2zzxec6vs64oky
- valory/decision_maker_abci:0.1.0:bafybeic77zhxf5a53ngfzacklmm3nag4t4jeufdhoeg3ykrmvknojtwipi
- valory/trader_abci:0.1.0:bafybeibi3rt3rdk4bvng3tlmwdxal3mk3bflq4cgq3fxyjwzpmhj3y6pmy
- valory/tx_settlement_multiplexer_abci:0.1.0:bafybeiey57caacd6d3ow25i6a2zuiinkx6kjtckdktannk7kijpd3p2zb4
- valory/market_manager_abci:0.1.0:bafybeigvw5tqei5xb272jb7retxiryhuhxxzupddmbdixgsmxzco3n2dde
- valory/decision_maker_abci:0.1.0:bafybeihm77vt53vu3xt6x7istsvaw75juptlynpriebgeltbil5evvhtue
- valory/trader_abci:0.1.0:bafybeiea2r67bzi5gkymu2pu2m3sg3lflke5m2finonak4uprqpbdcp2ru
default_ledger: ethereum
required_ledgers:
- ethereum
Expand Down Expand Up @@ -188,9 +188,10 @@ models:
slippage: ${float:0.01}
redeem_margin_days: ${int:15}
epsilon: ${float:0.1}
irrelevant_tools: ${set:{"openai-text-davinci-002", "openai-text-davinci-003", "openai-gpt-3.5-turbo",
"openai-gpt-4", "stabilityai-stable-diffusion-v1-5", "stabilityai-stable-diffusion-xl-beta-v2-2-2",
"stabilityai-stable-diffusion-512-v2-1", "stabilityai-stable-diffusion-768-v2-1"}}
irrelevant_tools: ${list:["openai-text-davinci-002", "openai-text-davinci-003",
"openai-gpt-3.5-turbo", "openai-gpt-4", "stabilityai-stable-diffusion-v1-5",
"stabilityai-stable-diffusion-xl-beta-v2-2-2", "stabilityai-stable-diffusion-512-v2-1",
"stabilityai-stable-diffusion-768-v2-1"]}
---
public_id: valory/p2p_libp2p_client:0.1.0
type: connection
Expand Down
9 changes: 3 additions & 6 deletions packages/valory/contracts/agent_registry/contract.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,9 @@ description: Agent Registry contract
license: Apache-2.0
aea_version: '>=1.0.0, <2.0.0'
fingerprint:
__init__.py: bafybeidey4syohls5hxmso6qsp5p4uhtzle5txv2mlbym6ktjzknich6oa
build/AgentRegistry.json: bafybeia4qi2vstrutejzrxfpbb6eift7va5cjs7bparaal2fafiiczuiyy
build/AgentRegistryL2.json: bafybeic2jylwfod4nmdtbs4izyxyi246pd3f35aoqyahnmyrvzn7j3sv4e
contract.py: bafybeibqwl52cnz64cysjd2jnjijuakdvyrffapxq65cdzx6g65gu42deq
tests/__init__.py: bafybeicl2oklx774jomlt6wwwegfdzrxh6iazjxwcyc7h4gepjljkpl4ji
tests/test_contract.py: bafybeicj535veqf35zb3ycu5iqjvqgj4a2kdmogmx5ba7fiolt5chah42a
__init__.py: bafybeid3wfzglolebuo6jrrsopswzu4lk77bm76mvw3euizlsjtnt3wmgu
build/AgentRegistry.json: bafybeicoe5elvvsv2neiirsdn4uddrilizmyib3x4mvpklr7olhj2kh4ue
contract.py: bafybeihrv6blme3v6diwci6zxxn72qbg5sanzmfq5tobhs4375ebcuyday
fingerprint_ignore_patterns: []
contracts: []
class_name: AgentRegistryContract
Expand Down
2 changes: 1 addition & 1 deletion packages/valory/contracts/mech/contract.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ fingerprint:
README.md: bafybeibl4uw7rs6mwh7zuvdnqmj2o2xyr7nx5qk3w7torwx3jg6farn6ca
__init__.py: bafybeicx5pxh3cxnml2biuuoebvafvu5tvy6mgkzyjzuubuoeebb5yzjsm
build/mech.json: bafybeihsfz7rdnf6cpa3c4eagvs4pw6jhr6pcsikstakejrlkuwvwzhw7m
contract.py: bafybeigypn3frcjr7mcmdoe5ubgoy57owm4bfcgtrcytiu76u7khthlvei
contract.py: bafybeifbfa6p3jcwn6j7s5aiiqxb3ne4vbmvoggr5zpptmd727gpsjqjpe
fingerprint_ignore_patterns: []
contracts: []
class_name: Mech
Expand Down
34 changes: 17 additions & 17 deletions packages/valory/services/trader/service.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ license: Apache-2.0
fingerprint:
README.md: bafybeigtuothskwyvrhfosps2bu6suauycolj67dpuxqvnicdrdu7yhtvq
fingerprint_ignore_patterns: []
agent: valory/trader:0.1.0:bafybeigoojaxpc7sz7vuswkxvpa5lp37lipuwc4qycztqk4hxdesmxqcda
agent: valory/trader:0.1.0:bafybeiba5eqawktwkpziiazxm5u6ftm7o3zytcbafqsjwt7zrr63o2yis4
number_of_agents: 4
deployment: {}
---
Expand Down Expand Up @@ -105,10 +105,10 @@ type: skill
slippage: ${SLIPPAGE:float:0.01}
redeem_margin_days: ${REDEEM_MARGIN_DAYS:int:15}
epsilon: ${EPSILON:float:0.1}
irrelevant_tools: ${IRRELEVANT_TOOLS:set:{"openai-text-davinci-002", "openai-text-davinci-003",
"openai-gpt-3.5-turbo", "openai-gpt-4", "stabilityai-stable-diffusion-v1-5",
"stabilityai-stable-diffusion-xl-beta-v2-2-2", "stabilityai-stable-diffusion-512-v2-1",
"stabilityai-stable-diffusion-768-v2-1"}}
irrelevant_tools: ${IRRELEVANT_TOOLS:list:["openai-text-davinci-002", "openai-text-davinci-003",
"openai-gpt-3.5-turbo", "openai-gpt-4", "stabilityai-stable-diffusion-v1-5",
"stabilityai-stable-diffusion-xl-beta-v2-2-2", "stabilityai-stable-diffusion-512-v2-1",
"stabilityai-stable-diffusion-768-v2-1"]}
benchmark_tool: &id005
args:
log_dir: ${LOG_DIR:str:/benchmarks}
Expand Down Expand Up @@ -174,10 +174,10 @@ type: skill
slippage: ${SLIPPAGE:float:0.01}
redeem_margin_days: ${REDEEM_MARGIN_DAYS:int:15}
epsilon: ${EPSILON:float:0.1}
irrelevant_tools: ${IRRELEVANT_TOOLS:set:{"openai-text-davinci-002", "openai-text-davinci-003",
"openai-gpt-3.5-turbo", "openai-gpt-4", "stabilityai-stable-diffusion-v1-5",
"stabilityai-stable-diffusion-xl-beta-v2-2-2", "stabilityai-stable-diffusion-512-v2-1",
"stabilityai-stable-diffusion-768-v2-1"}}
irrelevant_tools: ${IRRELEVANT_TOOLS:list:["openai-text-davinci-002", "openai-text-davinci-003",
"openai-gpt-3.5-turbo", "openai-gpt-4", "stabilityai-stable-diffusion-v1-5",
"stabilityai-stable-diffusion-xl-beta-v2-2-2", "stabilityai-stable-diffusion-512-v2-1",
"stabilityai-stable-diffusion-768-v2-1"]}
benchmark_tool: *id005
2:
models:
Expand Down Expand Up @@ -241,10 +241,10 @@ type: skill
slippage: ${SLIPPAGE:float:0.01}
redeem_margin_days: ${REDEEM_MARGIN_DAYS:int:15}
epsilon: ${EPSILON:float:0.1}
irrelevant_tools: ${IRRELEVANT_TOOLS:set:{"openai-text-davinci-002", "openai-text-davinci-003",
"openai-gpt-3.5-turbo", "openai-gpt-4", "stabilityai-stable-diffusion-v1-5",
"stabilityai-stable-diffusion-xl-beta-v2-2-2", "stabilityai-stable-diffusion-512-v2-1",
"stabilityai-stable-diffusion-768-v2-1"}}
irrelevant_tools: ${IRRELEVANT_TOOLS:list:["openai-text-davinci-002", "openai-text-davinci-003",
"openai-gpt-3.5-turbo", "openai-gpt-4", "stabilityai-stable-diffusion-v1-5",
"stabilityai-stable-diffusion-xl-beta-v2-2-2", "stabilityai-stable-diffusion-512-v2-1",
"stabilityai-stable-diffusion-768-v2-1"]}
benchmark_tool: *id005
3:
models:
Expand Down Expand Up @@ -308,10 +308,10 @@ type: skill
slippage: ${SLIPPAGE:float:0.01}
redeem_margin_days: ${REDEEM_MARGIN_DAYS:int:15}
epsilon: ${EPSILON:float:0.1}
irrelevant_tools: ${IRRELEVANT_TOOLS:set:{"openai-text-davinci-002", "openai-text-davinci-003",
"openai-gpt-3.5-turbo", "openai-gpt-4", "stabilityai-stable-diffusion-v1-5",
"stabilityai-stable-diffusion-xl-beta-v2-2-2", "stabilityai-stable-diffusion-512-v2-1",
"stabilityai-stable-diffusion-768-v2-1"}}
irrelevant_tools: ${IRRELEVANT_TOOLS:list:["openai-text-davinci-002", "openai-text-davinci-003",
"openai-gpt-3.5-turbo", "openai-gpt-4", "stabilityai-stable-diffusion-v1-5",
"stabilityai-stable-diffusion-xl-beta-v2-2-2", "stabilityai-stable-diffusion-512-v2-1",
"stabilityai-stable-diffusion-768-v2-1"]}
benchmark_tool: *id005
---
public_id: valory/ledger:0.19.0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@
)
from packages.valory.skills.decision_maker_abci.models import (
DecisionMakerParams,
EGreedyPolicy,
MultisendBatch,
)
from packages.valory.skills.decision_maker_abci.policy import EGreedyPolicy
from packages.valory.skills.decision_maker_abci.states.base import SynchronizedData
from packages.valory.skills.transaction_settlement_abci.payload_tools import (
hash_payload_to_hex,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@
from packages.valory.skills.decision_maker_abci.behaviours.sampling import (
SamplingBehaviour,
)
from packages.valory.skills.decision_maker_abci.behaviours.tool_selection import (
ToolSelectionBehaviour,
)
from packages.valory.skills.decision_maker_abci.rounds import DecisionMakerAbciApp


Expand All @@ -60,4 +63,5 @@ class AgentDecisionMakerRoundBehaviour(AbstractRoundBehaviour):
BetPlacementBehaviour, # type: ignore
RedeemBehaviour, # type: ignore
HandleFailedTxBehaviour, # type: ignore
ToolSelectionBehaviour, # type: ignore
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
# -*- coding: utf-8 -*-
# ------------------------------------------------------------------------------
#
# Copyright 2023 Valory AG
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# ------------------------------------------------------------------------------

"""This module contains the behaviour of the skill which is responsible for selecting a mech tool."""

import json
from typing import Any, Generator, List, Optional

from packages.valory.contracts.agent_registry.contract import AgentRegistryContract
from packages.valory.protocols.contract_api import ContractApiMessage
from packages.valory.skills.abstract_round_abci.base import get_name
from packages.valory.skills.decision_maker_abci.behaviours.base import (
CID_PREFIX,
DecisionMakerBaseBehaviour,
WaitableConditionType,
)
from packages.valory.skills.decision_maker_abci.models import AgentToolsSpecs
from packages.valory.skills.decision_maker_abci.payloads import ToolSelectionPayload
from packages.valory.skills.decision_maker_abci.policy import EGreedyPolicy
from packages.valory.skills.decision_maker_abci.states.tool_selection import (
ToolSelectionRound,
)


class ToolSelectionBehaviour(DecisionMakerBaseBehaviour):
"""A behaviour in which the agents select a mech tool."""

matching_round = ToolSelectionRound

def __init__(self, **kwargs: Any) -> None:
"""Initialize Behaviour."""
super().__init__(**kwargs)
self._mech_id: int = 0
self._mech_hash: str = ""
self.mech_tools: Optional[List[str]] = None

@property
def mech_id(self) -> int:
"""Get the mech's id."""
return self._mech_id

@mech_id.setter
def mech_id(self, mech_id: int) -> None:
"""Set the mech's id."""
self._mech_id = mech_id

@property
def mech_hash(self) -> str:
"""Get the hash of the mech agent."""
return self._mech_hash

@mech_hash.setter
def mech_hash(self, mech_hash: str) -> None:
"""Set the hash of the mech agent."""
self._mech_hash = mech_hash

@property
def mech_tools_api(self) -> AgentToolsSpecs:
"""Get the mech agent api specs."""
return self.context.agent_tools

def set_mech_agent_specs(self) -> None:
"""Set the mech's agent specs."""
full_ipfs_hash = CID_PREFIX + self.mech_hash
ipfs_link = self.params.ipfs_address + full_ipfs_hash
# The url needs to be dynamically generated as it depends on the ipfs hash
self.mech_tools_api.__dict__["_frozen"] = False
self.mech_tools_api.url = ipfs_link
self.mech_tools_api.__dict__["_frozen"] = True

def _get_mech_id(self) -> WaitableConditionType:
"""Get the mech's id."""
result = yield from self._mech_contract_interact(
contract_callable="get_mech_id",
data_key="id",
placeholder=get_name(ToolSelectionBehaviour.mech_id),
)

return result

def _get_mech_hash(self) -> WaitableConditionType:
"""Get the mech's hash."""
result = yield from self.contract_interact(
performative=ContractApiMessage.Performative.GET_RAW_TRANSACTION, # type: ignore
contract_address=self.params.agent_registry_address,
contract_public_id=AgentRegistryContract.contract_id,
contract_callable="get_hash",
data_key="hash",
placeholder=get_name(ToolSelectionBehaviour.mech_hash),
agent_id=self.mech_id,
)
return result

def _get_mech_tools(self) -> WaitableConditionType:
"""Get the mech agent's tools from IPFS."""
specs = self.mech_tools_api.get_spec()
res_raw = yield from self.get_http_response(**specs)
res = self.mech_tools_api.process_response(res_raw)

if self.mech_tools_api.is_retries_exceeded():
error = "Retries were exceeded while trying to get the mech agent's data."
self.context.logger.error(error)
return True

if res is None:
msg = f"Could not get the mech agent's tools from {self.mech_tools_api.api_id}"
self.context.logger.error(msg)
self.mech_tools_api.increment_retries()
return False

self.context.logger.info(f"Retrieved the mech agent's tools: {res}.")
if len(res) == 0:
res = None
self.context.logger.error("The mech agent's tools are empty!")
self.mech_tools = res
self.mech_tools_api.reset_retries()
return True

def _get_tools(
self,
) -> Generator[None, None, None]:
"""Get the Mech's tools."""
for step in (
self._get_mech_id,
self._get_mech_hash,
self._get_mech_tools,
):
yield from self.wait_for_condition_with_sleep(step)

def _adjust_policy_tools(self, tools: List[str]) -> None:
"""Add or remove tools from the policy to match the remote tools."""
# remove tools if they are not available anymore
local = set(self.synchronized_data.available_mech_tools)
remote = set(tools)
relevant_remote = remote - self.params.irrelevant_tools
removed_tools_idx = [
idx for idx, tool in enumerate(local) if tool not in relevant_remote
]
if len(removed_tools_idx) > 0:
self.policy.remove_tools(removed_tools_idx)

# add tools if there are new ones available
new_tools = remote - local
n_new_tools = len(new_tools)
if n_new_tools > 0:
self.policy.add_new_tools(n_new_tools)

def _set_policy(self, tools: List[str]) -> None:
"""Set the E Greedy Policy."""
if self.synchronized_data.period_count == 0:
self._policy = EGreedyPolicy.initial_state(self.params.epsilon, len(tools))
else:
self._policy = self.synchronized_data.policy
self._adjust_policy_tools(tools)

def _select_tool(self) -> Generator[None, None, Optional[int]]:
"""Select a Mech tool based on an e-greedy policy and return its index."""
yield from self._get_tools()
if self.mech_tools is None:
return None

self._set_policy(self.mech_tools)
return self.policy.select_tool()

def async_act(self) -> Generator:
"""Do the action."""

with self.context.benchmark_tool.measure(self.behaviour_id).local():
mech_tools = policy = None
selected_tool = yield from self._select_tool()
if selected_tool is not None:
mech_tools = json.dumps(self.mech_tools)
policy = self.policy.serialize()

payload = ToolSelectionPayload(
self.context.agent_address,
mech_tools,
policy,
selected_tool,
)

yield from self.finish_behaviour(payload)
Loading
Loading