Skip to content

Commit

Permalink
Merge pull request #50 from gnosis/evan/monitor-omen
Browse files Browse the repository at this point in the history
Support monitoring for deployed Omen agents
  • Loading branch information
evangriffiths authored Feb 26, 2024
2 parents b5a119c + 621483d commit e7d4b79
Show file tree
Hide file tree
Showing 7 changed files with 92 additions and 31 deletions.
3 changes: 2 additions & 1 deletion prediction_market_agent_tooling/markets/omen/data_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,8 @@ def boolean_outcome(self) -> bool:
if not self.is_resolved:
raise ValueError(f"Bet with title {self.title} is not resolved.")

return get_boolean_outcome(check_not_none(self.currentAnswer))
outcome: str = self.outcomes[int(check_not_none(self.currentAnswer), 16)]
return get_boolean_outcome(outcome)


class OmenBet(BaseModel):
Expand Down
2 changes: 1 addition & 1 deletion prediction_market_agent_tooling/markets/omen/omen.py
Original file line number Diff line number Diff line change
Expand Up @@ -705,7 +705,7 @@ def to_int_timestamp(dt: datetime) -> int:
return int(dt.timestamp())


def get_resolved_bets(
def get_bets(
better_address: ChecksumAddress,
start_time: datetime,
end_time: t.Optional[datetime],
Expand Down
24 changes: 23 additions & 1 deletion prediction_market_agent_tooling/monitor/markets/manifold.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
from datetime import datetime

from prediction_market_agent_tooling.markets.data_models import ResolvedBet
from prediction_market_agent_tooling.markets.manifold.api import (
get_authenticated_user,
get_resolved_manifold_bets,
manifold_to_generic_resolved_bet,
)
from prediction_market_agent_tooling.monitor.monitor import DeployedAgent
from prediction_market_agent_tooling.monitor.monitor import (
DeployedAgent,
MonitorSettings,
)


class DeployedManifoldAgent(DeployedAgent):
Expand All @@ -16,3 +22,19 @@ def get_resolved_bets(self) -> list[ResolvedBet]:
end_time=None,
)
return [manifold_to_generic_resolved_bet(b) for b in manifold_bets]

@staticmethod
def from_monitor_settings(
settings: MonitorSettings, start_time: datetime
) -> list[DeployedAgent]:
agents = []
for key in settings.MANIFOLD_API_KEYS:
agents.append(
DeployedManifoldAgent(
name="ManifoldAgent",
start_time=start_time,
manifold_user_id=get_authenticated_user(key).id,
)
)
else:
return []
30 changes: 26 additions & 4 deletions prediction_market_agent_tooling/monitor/markets/omen.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,38 @@
from datetime import datetime

from web3 import Web3

from prediction_market_agent_tooling.gtypes import ChecksumAddress
from prediction_market_agent_tooling.markets.data_models import ResolvedBet
from prediction_market_agent_tooling.markets.omen.omen import get_resolved_bets
from prediction_market_agent_tooling.monitor.monitor import DeployedAgent
from prediction_market_agent_tooling.markets.omen.omen import get_bets
from prediction_market_agent_tooling.monitor.monitor import (
DeployedAgent,
MonitorSettings,
)


class DeployedOmenAgent(DeployedAgent):
wallet_address: ChecksumAddress

def get_resolved_bets(self) -> list[ResolvedBet]:
bets = get_resolved_bets(
bets = get_bets(
better_address=self.wallet_address,
start_time=self.start_time,
end_time=None,
)
return [b.to_generic_resolved_bet() for b in bets]
return [b.to_generic_resolved_bet() for b in bets if b.fpmm.is_resolved]

@staticmethod
def from_monitor_settings(
settings: MonitorSettings, start_time: datetime
) -> list[DeployedAgent]:
if settings.BET_FROM_ADDRESS:
return [
DeployedOmenAgent(
name="OmenAgent",
start_time=start_time,
wallet_address=Web3.to_checksum_address(settings.BET_FROM_ADDRESS),
)
]
else:
return []
17 changes: 17 additions & 0 deletions prediction_market_agent_tooling/monitor/monitor.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import pandas as pd
import streamlit as st
from pydantic import BaseModel
from pydantic_settings import BaseSettings, SettingsConfigDict

from prediction_market_agent_tooling.benchmark.utils import (
CancelableMarketResolution,
Expand All @@ -16,6 +17,16 @@
from prediction_market_agent_tooling.tools.utils import should_not_happen


class MonitorSettings(BaseSettings):
model_config = SettingsConfigDict(
env_file=".env.monitor", env_file_encoding="utf-8", extra="ignore"
)

MANIFOLD_API_KEYS: list[str] = []
BET_FROM_ADDRESS: t.Optional[str] = None
PAST_N_WEEKS: int = 1


class DeployedAgent(BaseModel):
name: str
start_time: datetime = datetime.utcnow()
Expand All @@ -24,6 +35,12 @@ class DeployedAgent(BaseModel):
def get_resolved_bets(self) -> list[ResolvedBet]:
raise NotImplementedError("Subclasses must implement this method.")

@staticmethod
def from_monitor_settings(
settings: MonitorSettings, start_time: datetime
) -> list["DeployedAgent"]:
raise NotImplementedError("Subclasses must implement this method.")


def monitor_agent(agent: DeployedAgent) -> None:
agent_bets = agent.get_resolved_bets()
Expand Down
43 changes: 21 additions & 22 deletions prediction_market_agent_tooling/monitor/monitor_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,35 @@

import pytz
import streamlit as st
from pydantic_settings import BaseSettings, SettingsConfigDict

from prediction_market_agent_tooling.benchmark.utils import get_manifold_markets_dated
from prediction_market_agent_tooling.markets.manifold.api import get_authenticated_user
from prediction_market_agent_tooling.markets.markets import MarketType
from prediction_market_agent_tooling.monitor.markets.manifold import (
DeployedManifoldAgent,
)
from prediction_market_agent_tooling.monitor.markets.omen import DeployedOmenAgent
from prediction_market_agent_tooling.monitor.monitor import (
DeployedAgent,
MonitorSettings,
monitor_agent,
monitor_market,
)
from prediction_market_agent_tooling.tools.utils import check_not_none

DEPLOYED_AGENT_TYPE_MAP: dict[MarketType, type[DeployedAgent]] = {
MarketType.MANIFOLD: DeployedManifoldAgent,
MarketType.OMEN: DeployedOmenAgent,
}

class MonitorSettings(BaseSettings):
model_config = SettingsConfigDict(
env_file=".env.monitor", env_file_encoding="utf-8", extra="ignore"
)

MANIFOLD_API_KEYS: list[str] = []
PAST_N_WEEKS: int = 1
def get_deployed_agents(
market_type: MarketType, settings: MonitorSettings, start_time: datetime
) -> list[DeployedAgent]:
cls = DEPLOYED_AGENT_TYPE_MAP.get(market_type)
if cls:
return cls.from_monitor_settings(settings=settings, start_time=start_time)
else:
raise ValueError(f"Unknown market type: {market_type}")


def monitor_app() -> None:
Expand All @@ -44,10 +51,6 @@ def monitor_app() -> None:
st.selectbox(label="Market type", options=list(MarketType), index=0)
)

if market_type != MarketType.MANIFOLD:
st.warning("Only Manifold markets are supported for now.")
return

st.subheader("Market resolution")
open_markets = get_manifold_markets_dated(oldest_date=start_time, filter_="open")
resolved_markets = [
Expand All @@ -57,17 +60,13 @@ def monitor_app() -> None:
]
monitor_market(open_markets=open_markets, resolved_markets=resolved_markets)

with st.spinner("Loading Manifold agents..."):
agents: list[DeployedManifoldAgent] = []
for key in settings.MANIFOLD_API_KEYS:
manifold_user = get_authenticated_user(key)
agents.append(
DeployedManifoldAgent(
name=manifold_user.name,
manifold_user_id=manifold_user.id,
start_time=start_time,
)
with st.spinner("Loading agents..."):
agents: list[DeployedAgent] = [
agent
for agent in get_deployed_agents(
market_type=market_type, settings=settings, start_time=start_time
)
]

st.subheader("Agent bets")
for agent in agents:
Expand Down
4 changes: 2 additions & 2 deletions tests/markets/test_omen.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
OmenAgentMarket,
binary_omen_buy_outcome_tx,
binary_omen_sell_outcome_tx,
get_bets,
get_market,
get_resolved_bets,
pick_binary_market,
)
from tests.utils import RUN_PAID_TESTS
Expand Down Expand Up @@ -60,7 +60,7 @@ def test_omen_buy_and_sell_outcome() -> None:

def test_get_bets() -> None:
AN_ADDRESS = Web3.to_checksum_address("0x3666DA333dAdD05083FEf9FF6dDEe588d26E4307")
bets = get_resolved_bets(
bets = get_bets(
better_address=AN_ADDRESS,
start_time=datetime(2024, 2, 20),
end_time=datetime(2024, 2, 21),
Expand Down

0 comments on commit e7d4b79

Please sign in to comment.