prediction-market-agent-tooling 0.49.1__py3-none-any.whl → 0.50.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- prediction_market_agent_tooling/benchmark/agents.py +6 -6
- prediction_market_agent_tooling/deploy/agent.py +5 -5
- prediction_market_agent_tooling/deploy/betting_strategy.py +83 -3
- prediction_market_agent_tooling/deploy/gcp/kubernetes_models.py +3 -4
- prediction_market_agent_tooling/gtypes.py +3 -2
- prediction_market_agent_tooling/jobs/jobs_models.py +3 -3
- prediction_market_agent_tooling/jobs/omen/omen_jobs.py +2 -2
- prediction_market_agent_tooling/markets/agent_market.py +13 -17
- prediction_market_agent_tooling/markets/data_models.py +3 -3
- prediction_market_agent_tooling/markets/manifold/api.py +6 -6
- prediction_market_agent_tooling/markets/manifold/data_models.py +13 -23
- prediction_market_agent_tooling/markets/manifold/manifold.py +2 -2
- prediction_market_agent_tooling/markets/markets.py +7 -3
- prediction_market_agent_tooling/markets/metaculus/api.py +2 -3
- prediction_market_agent_tooling/markets/metaculus/data_models.py +11 -10
- prediction_market_agent_tooling/markets/metaculus/metaculus.py +2 -2
- prediction_market_agent_tooling/markets/omen/data_models.py +35 -22
- prediction_market_agent_tooling/markets/omen/omen.py +13 -9
- prediction_market_agent_tooling/markets/omen/omen_contracts.py +4 -2
- prediction_market_agent_tooling/markets/omen/omen_resolving.py +3 -4
- prediction_market_agent_tooling/markets/omen/omen_subgraph_handler.py +46 -33
- prediction_market_agent_tooling/markets/polymarket/api.py +1 -1
- prediction_market_agent_tooling/markets/polymarket/data_models.py +5 -6
- prediction_market_agent_tooling/markets/polymarket/data_models_web.py +14 -14
- prediction_market_agent_tooling/markets/polymarket/polymarket.py +2 -2
- prediction_market_agent_tooling/monitor/markets/manifold.py +2 -2
- prediction_market_agent_tooling/monitor/markets/metaculus.py +2 -2
- prediction_market_agent_tooling/monitor/markets/omen.py +2 -2
- prediction_market_agent_tooling/monitor/markets/polymarket.py +2 -2
- prediction_market_agent_tooling/monitor/monitor.py +5 -15
- prediction_market_agent_tooling/monitor/monitor_app.py +7 -8
- prediction_market_agent_tooling/tools/contract.py +3 -7
- prediction_market_agent_tooling/tools/datetime_utc.py +74 -0
- prediction_market_agent_tooling/tools/httpx_cached_client.py +11 -0
- prediction_market_agent_tooling/tools/is_predictable.py +1 -1
- prediction_market_agent_tooling/tools/langfuse_client_utils.py +16 -11
- prediction_market_agent_tooling/tools/tavily_storage/tavily_models.py +5 -5
- prediction_market_agent_tooling/tools/utils.py +28 -52
- {prediction_market_agent_tooling-0.49.1.dist-info → prediction_market_agent_tooling-0.50.0.dist-info}/METADATA +5 -2
- {prediction_market_agent_tooling-0.49.1.dist-info → prediction_market_agent_tooling-0.50.0.dist-info}/RECORD +43 -41
- {prediction_market_agent_tooling-0.49.1.dist-info → prediction_market_agent_tooling-0.50.0.dist-info}/LICENSE +0 -0
- {prediction_market_agent_tooling-0.49.1.dist-info → prediction_market_agent_tooling-0.50.0.dist-info}/WHEEL +0 -0
- {prediction_market_agent_tooling-0.49.1.dist-info → prediction_market_agent_tooling-0.50.0.dist-info}/entry_points.txt +0 -0
@@ -1,5 +1,4 @@
|
|
1
1
|
import typing as t
|
2
|
-
from datetime import datetime
|
3
2
|
|
4
3
|
from prediction_market_agent_tooling.markets.agent_market import (
|
5
4
|
AgentMarket,
|
@@ -16,6 +15,7 @@ from prediction_market_agent_tooling.markets.polymarket.data_models import (
|
|
16
15
|
from prediction_market_agent_tooling.markets.polymarket.data_models_web import (
|
17
16
|
POLYMARKET_BASE_URL,
|
18
17
|
)
|
18
|
+
from prediction_market_agent_tooling.tools.utils import DatetimeUTC
|
19
19
|
|
20
20
|
|
21
21
|
class PolymarketAgentMarket(AgentMarket):
|
@@ -54,7 +54,7 @@ class PolymarketAgentMarket(AgentMarket):
|
|
54
54
|
limit: int,
|
55
55
|
sort_by: SortBy = SortBy.NONE,
|
56
56
|
filter_by: FilterBy = FilterBy.OPEN,
|
57
|
-
created_after: t.Optional[
|
57
|
+
created_after: t.Optional[DatetimeUTC] = None,
|
58
58
|
excluded_questions: set[str] | None = None,
|
59
59
|
) -> t.Sequence["PolymarketAgentMarket"]:
|
60
60
|
if sort_by != SortBy.NONE:
|
@@ -15,7 +15,7 @@ from prediction_market_agent_tooling.monitor.monitor import (
|
|
15
15
|
DeployedAgent,
|
16
16
|
KubernetesCronJob,
|
17
17
|
)
|
18
|
-
from prediction_market_agent_tooling.tools.utils import
|
18
|
+
from prediction_market_agent_tooling.tools.utils import DatetimeUTC
|
19
19
|
|
20
20
|
|
21
21
|
class DeployedManifoldAgent(DeployedAgent):
|
@@ -57,7 +57,7 @@ class DeployedManifoldAgent(DeployedAgent):
|
|
57
57
|
@staticmethod
|
58
58
|
def from_api_keys(
|
59
59
|
name: str,
|
60
|
-
start_time:
|
60
|
+
start_time: DatetimeUTC,
|
61
61
|
api_keys: APIKeys,
|
62
62
|
) -> "DeployedManifoldAgent":
|
63
63
|
return DeployedManifoldAgent(
|
@@ -4,7 +4,7 @@ from google.cloud.functions_v2.types.functions import Function
|
|
4
4
|
|
5
5
|
from prediction_market_agent_tooling.config import APIKeys
|
6
6
|
from prediction_market_agent_tooling.deploy.constants import MARKET_TYPE_KEY
|
7
|
-
from prediction_market_agent_tooling.gtypes import
|
7
|
+
from prediction_market_agent_tooling.gtypes import DatetimeUTC
|
8
8
|
from prediction_market_agent_tooling.markets.data_models import ResolvedBet
|
9
9
|
from prediction_market_agent_tooling.markets.markets import MarketType
|
10
10
|
from prediction_market_agent_tooling.monitor.monitor import DeployedAgent
|
@@ -23,7 +23,7 @@ class DeployedMetaculusAgent(DeployedAgent):
|
|
23
23
|
@staticmethod
|
24
24
|
def from_api_keys(
|
25
25
|
name: str,
|
26
|
-
start_time:
|
26
|
+
start_time: DatetimeUTC,
|
27
27
|
api_keys: APIKeys,
|
28
28
|
) -> "DeployedMetaculusAgent":
|
29
29
|
return DeployedMetaculusAgent(
|
@@ -4,7 +4,7 @@ from google.cloud.functions_v2.types.functions import Function
|
|
4
4
|
|
5
5
|
from prediction_market_agent_tooling.config import APIKeys
|
6
6
|
from prediction_market_agent_tooling.deploy.constants import MARKET_TYPE_KEY
|
7
|
-
from prediction_market_agent_tooling.gtypes import ChecksumAddress,
|
7
|
+
from prediction_market_agent_tooling.gtypes import ChecksumAddress, DatetimeUTC
|
8
8
|
from prediction_market_agent_tooling.markets.data_models import ResolvedBet
|
9
9
|
from prediction_market_agent_tooling.markets.markets import MarketType
|
10
10
|
from prediction_market_agent_tooling.markets.omen.omen_subgraph_handler import (
|
@@ -57,7 +57,7 @@ class DeployedOmenAgent(DeployedAgent):
|
|
57
57
|
@staticmethod
|
58
58
|
def from_api_keys(
|
59
59
|
name: str,
|
60
|
-
start_time:
|
60
|
+
start_time: DatetimeUTC,
|
61
61
|
api_keys: APIKeys,
|
62
62
|
) -> "DeployedOmenAgent":
|
63
63
|
return DeployedOmenAgent(
|
@@ -4,7 +4,7 @@ from google.cloud.functions_v2.types.functions import Function
|
|
4
4
|
|
5
5
|
from prediction_market_agent_tooling.config import APIKeys
|
6
6
|
from prediction_market_agent_tooling.deploy.constants import MARKET_TYPE_KEY
|
7
|
-
from prediction_market_agent_tooling.gtypes import ChecksumAddress,
|
7
|
+
from prediction_market_agent_tooling.gtypes import ChecksumAddress, DatetimeUTC
|
8
8
|
from prediction_market_agent_tooling.markets.data_models import ResolvedBet
|
9
9
|
from prediction_market_agent_tooling.markets.markets import MarketType
|
10
10
|
from prediction_market_agent_tooling.monitor.monitor import DeployedAgent
|
@@ -25,7 +25,7 @@ class DeployedPolymarketAgent(DeployedAgent):
|
|
25
25
|
@staticmethod
|
26
26
|
def from_api_keys(
|
27
27
|
name: str,
|
28
|
-
start_time:
|
28
|
+
start_time: DatetimeUTC,
|
29
29
|
api_keys: APIKeys,
|
30
30
|
) -> "DeployedPolymarketAgent":
|
31
31
|
return DeployedPolymarketAgent(
|
@@ -8,7 +8,7 @@ import numpy as np
|
|
8
8
|
import pandas as pd
|
9
9
|
import streamlit as st
|
10
10
|
from google.cloud.functions_v2.types.functions import Function
|
11
|
-
from pydantic import BaseModel
|
11
|
+
from pydantic import BaseModel
|
12
12
|
|
13
13
|
from prediction_market_agent_tooling.config import APIKeys
|
14
14
|
from prediction_market_agent_tooling.deploy.gcp.kubernetes_models import (
|
@@ -26,9 +26,8 @@ from prediction_market_agent_tooling.markets.agent_market import AgentMarket
|
|
26
26
|
from prediction_market_agent_tooling.markets.data_models import Resolution, ResolvedBet
|
27
27
|
from prediction_market_agent_tooling.tools.parallelism import par_map
|
28
28
|
from prediction_market_agent_tooling.tools.utils import (
|
29
|
-
|
29
|
+
DatetimeUTC,
|
30
30
|
check_not_none,
|
31
|
-
convert_to_utc_datetime,
|
32
31
|
should_not_happen,
|
33
32
|
)
|
34
33
|
|
@@ -40,21 +39,12 @@ class DeployedAgent(BaseModel):
|
|
40
39
|
|
41
40
|
name: str
|
42
41
|
|
43
|
-
start_time:
|
44
|
-
end_time:
|
45
|
-
DatetimeWithTimezone
|
46
|
-
] = None # TODO: If we want end time, we need to store agents somewhere, not just query them from functions.
|
42
|
+
start_time: DatetimeUTC
|
43
|
+
end_time: DatetimeUTC | None = None # TODO: If we want end time, we need to store agents somewhere, not just query them from functions.
|
47
44
|
|
48
45
|
raw_labels: dict[str, str] | None = None
|
49
46
|
raw_env_vars: dict[str, str] | None = None
|
50
47
|
|
51
|
-
_add_timezone_validator_start_time = field_validator("start_time")(
|
52
|
-
convert_to_utc_datetime
|
53
|
-
)
|
54
|
-
_add_timezone_validator_end_time = field_validator("end_time")(
|
55
|
-
convert_to_utc_datetime
|
56
|
-
)
|
57
|
-
|
58
48
|
def model_dump_prefixed(self) -> dict[str, t.Any]:
|
59
49
|
return {
|
60
50
|
self.PREFIX + k: v for k, v in self.model_dump().items() if v is not None
|
@@ -93,7 +83,7 @@ class DeployedAgent(BaseModel):
|
|
93
83
|
@staticmethod
|
94
84
|
def from_api_keys(
|
95
85
|
name: str,
|
96
|
-
start_time:
|
86
|
+
start_time: DatetimeUTC,
|
97
87
|
api_keys: APIKeys,
|
98
88
|
) -> "DeployedAgent":
|
99
89
|
raise NotImplementedError("Subclasses must implement this method.")
|
@@ -1,7 +1,6 @@
|
|
1
1
|
import typing as t
|
2
2
|
from datetime import date, datetime, timedelta
|
3
3
|
|
4
|
-
import pytz
|
5
4
|
import streamlit as st
|
6
5
|
|
7
6
|
from prediction_market_agent_tooling.markets.agent_market import (
|
@@ -27,9 +26,9 @@ from prediction_market_agent_tooling.monitor.monitor import (
|
|
27
26
|
)
|
28
27
|
from prediction_market_agent_tooling.monitor.monitor_settings import MonitorSettings
|
29
28
|
from prediction_market_agent_tooling.tools.utils import (
|
30
|
-
|
29
|
+
DatetimeUTC,
|
31
30
|
check_not_none,
|
32
|
-
|
31
|
+
utc_datetime,
|
33
32
|
utcnow,
|
34
33
|
)
|
35
34
|
|
@@ -46,7 +45,7 @@ MARKET_TYPE_TO_DEPLOYED_AGENT: dict[MarketType, type[DeployedAgent]] = {
|
|
46
45
|
def get_deployed_agents(
|
47
46
|
market_type: MarketType,
|
48
47
|
settings: MonitorSettings,
|
49
|
-
start_time:
|
48
|
+
start_time: DatetimeUTC | None,
|
50
49
|
) -> list[DeployedAgent]:
|
51
50
|
cls = MARKET_TYPE_TO_DEPLOYED_AGENT.get(market_type)
|
52
51
|
if cls is None:
|
@@ -76,7 +75,7 @@ def get_deployed_agents(
|
|
76
75
|
|
77
76
|
|
78
77
|
def get_open_and_resolved_markets(
|
79
|
-
start_time:
|
78
|
+
start_time: DatetimeUTC,
|
80
79
|
market_type: MarketType,
|
81
80
|
) -> tuple[t.Sequence[AgentMarket], t.Sequence[AgentMarket]]:
|
82
81
|
cls = market_type.market_class
|
@@ -103,8 +102,8 @@ def monitor_app(
|
|
103
102
|
market_type: MarketType = check_not_none(
|
104
103
|
st.selectbox(label="Market type", options=enabled_market_types, index=0)
|
105
104
|
)
|
106
|
-
start_time:
|
107
|
-
|
105
|
+
start_time: DatetimeUTC | None = (
|
106
|
+
DatetimeUTC.from_datetime(
|
108
107
|
datetime.combine(
|
109
108
|
t.cast(
|
110
109
|
# This will be always a date for us, so casting.
|
@@ -131,7 +130,7 @@ def monitor_app(
|
|
131
130
|
oldest_start_time = (
|
132
131
|
min(agent.start_time for agent in agents)
|
133
132
|
if agents
|
134
|
-
else
|
133
|
+
else utc_datetime(2020, 1, 1)
|
135
134
|
)
|
136
135
|
|
137
136
|
st.header("Market Info")
|
@@ -22,11 +22,7 @@ from prediction_market_agent_tooling.tools.gnosis_rpc import (
|
|
22
22
|
GNOSIS_NETWORK_ID,
|
23
23
|
GNOSIS_RPC_URL,
|
24
24
|
)
|
25
|
-
from prediction_market_agent_tooling.tools.utils import
|
26
|
-
DatetimeWithTimezone,
|
27
|
-
should_not_happen,
|
28
|
-
utc_timestamp_to_utc_datetime,
|
29
|
-
)
|
25
|
+
from prediction_market_agent_tooling.tools.utils import DatetimeUTC, should_not_happen
|
30
26
|
from prediction_market_agent_tooling.tools.web3_utils import (
|
31
27
|
call_function_on_contract,
|
32
28
|
send_function_on_contract_tx,
|
@@ -457,8 +453,8 @@ class DebuggingContract(ContractOnGnosisChain):
|
|
457
453
|
def get_now(
|
458
454
|
self,
|
459
455
|
web3: Web3 | None = None,
|
460
|
-
) ->
|
461
|
-
return
|
456
|
+
) -> DatetimeUTC:
|
457
|
+
return DatetimeUTC.to_datetime_utc(self.getNow(web3))
|
462
458
|
|
463
459
|
def inc(
|
464
460
|
self,
|
@@ -0,0 +1,74 @@
|
|
1
|
+
import typing as t
|
2
|
+
from datetime import datetime, timedelta
|
3
|
+
|
4
|
+
import pytz
|
5
|
+
from dateutil import parser
|
6
|
+
from pydantic import GetCoreSchemaHandler
|
7
|
+
from pydantic_core import CoreSchema, core_schema
|
8
|
+
|
9
|
+
from prediction_market_agent_tooling.loggers import logger
|
10
|
+
|
11
|
+
|
12
|
+
class DatetimeUTC(datetime):
|
13
|
+
"""
|
14
|
+
As a subclass of `datetime` instead of `NewType` because otherwise it doesn't work with issubclass command which is required for SQLModel/Pydantic.
|
15
|
+
"""
|
16
|
+
|
17
|
+
def __new__(cls, *args, **kwargs) -> "DatetimeUTC": # type: ignore[no-untyped-def] # Pickling doesn't work if I copy-paste arguments from datetime's __new__.
|
18
|
+
if len(args) >= 8:
|
19
|
+
# Start of Selection
|
20
|
+
args = args[:7] + (pytz.UTC,) + args[8:]
|
21
|
+
else:
|
22
|
+
kwargs["tzinfo"] = pytz.UTC
|
23
|
+
return super().__new__(cls, *args, **kwargs)
|
24
|
+
|
25
|
+
@classmethod
|
26
|
+
def _validate(cls, value: t.Any) -> "DatetimeUTC":
|
27
|
+
if not isinstance(value, (datetime, int, str)):
|
28
|
+
raise TypeError(
|
29
|
+
f"Expected datetime, timestamp or string, got {type(value)}"
|
30
|
+
)
|
31
|
+
return cls.to_datetime_utc(value)
|
32
|
+
|
33
|
+
@classmethod
|
34
|
+
def __get_pydantic_core_schema__(
|
35
|
+
cls, source_type: t.Any, handler: GetCoreSchemaHandler
|
36
|
+
) -> CoreSchema:
|
37
|
+
dt_schema = handler(datetime)
|
38
|
+
return core_schema.no_info_after_validator_function(cls._validate, dt_schema)
|
39
|
+
|
40
|
+
@staticmethod
|
41
|
+
def from_datetime(dt: datetime) -> "DatetimeUTC":
|
42
|
+
"""
|
43
|
+
Converts a datetime object to DatetimeUTC, ensuring it is timezone-aware in UTC.
|
44
|
+
"""
|
45
|
+
if dt.tzinfo is None:
|
46
|
+
logger.warning(
|
47
|
+
f"tzinfo not provided, assuming the timezone of {dt=} is UTC."
|
48
|
+
)
|
49
|
+
dt = dt.replace(tzinfo=pytz.UTC)
|
50
|
+
else:
|
51
|
+
dt = dt.astimezone(pytz.UTC)
|
52
|
+
return DatetimeUTC(
|
53
|
+
dt.year,
|
54
|
+
dt.month,
|
55
|
+
dt.day,
|
56
|
+
dt.hour,
|
57
|
+
dt.minute,
|
58
|
+
dt.second,
|
59
|
+
dt.microsecond,
|
60
|
+
tzinfo=pytz.UTC,
|
61
|
+
)
|
62
|
+
|
63
|
+
@staticmethod
|
64
|
+
def to_datetime_utc(value: datetime | int | str) -> "DatetimeUTC":
|
65
|
+
if isinstance(value, int):
|
66
|
+
# Divide by 1000 if the timestamp is assumed to be in miliseconds (if not, 1e11 would be year 5138).
|
67
|
+
value = int(value / 1000) if value > 1e11 else value
|
68
|
+
# In the past, we had bugged data where timestamp was huge and Python errored out.
|
69
|
+
max_timestamp = int((datetime.max - timedelta(days=1)).timestamp())
|
70
|
+
value = min(value, max_timestamp)
|
71
|
+
value = datetime.fromtimestamp(value, tz=pytz.UTC)
|
72
|
+
elif isinstance(value, str):
|
73
|
+
value = parser.parse(value)
|
74
|
+
return DatetimeUTC.from_datetime(value)
|
@@ -0,0 +1,11 @@
|
|
1
|
+
import hishel
|
2
|
+
|
3
|
+
|
4
|
+
class HttpxCachedClient:
|
5
|
+
def __init__(self) -> None:
|
6
|
+
storage = hishel.FileStorage(ttl=3600, check_ttl_every=600)
|
7
|
+
controller = hishel.Controller(force_cache=True)
|
8
|
+
self.client = hishel.CacheClient(storage=storage, controller=controller)
|
9
|
+
|
10
|
+
def get_client(self) -> hishel.CacheClient:
|
11
|
+
return self.client
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import tenacity
|
2
|
-
from loguru import logger
|
3
2
|
|
4
3
|
from prediction_market_agent_tooling.config import APIKeys
|
4
|
+
from prediction_market_agent_tooling.loggers import logger
|
5
5
|
from prediction_market_agent_tooling.tools.cache import persistent_inmemory_cache
|
6
6
|
from prediction_market_agent_tooling.tools.langfuse_ import (
|
7
7
|
get_langfuse_langchain_config,
|
@@ -1,5 +1,4 @@
|
|
1
1
|
import typing as t
|
2
|
-
from datetime import datetime
|
3
2
|
|
4
3
|
import numpy as np
|
5
4
|
from langfuse import Langfuse
|
@@ -14,15 +13,19 @@ from prediction_market_agent_tooling.markets.data_models import (
|
|
14
13
|
TradeType,
|
15
14
|
)
|
16
15
|
from prediction_market_agent_tooling.markets.omen.omen import OmenAgentMarket
|
17
|
-
from prediction_market_agent_tooling.tools.utils import
|
16
|
+
from prediction_market_agent_tooling.tools.utils import DatetimeUTC
|
18
17
|
|
19
18
|
|
20
19
|
class ProcessMarketTrace(BaseModel):
|
21
|
-
timestamp:
|
20
|
+
timestamp: int
|
22
21
|
market: OmenAgentMarket
|
23
22
|
answer: ProbabilisticAnswer
|
24
23
|
trades: list[PlacedTrade]
|
25
24
|
|
25
|
+
@property
|
26
|
+
def timestamp_datetime(self) -> DatetimeUTC:
|
27
|
+
return DatetimeUTC.to_datetime_utc(self.timestamp)
|
28
|
+
|
26
29
|
@property
|
27
30
|
def buy_trade(self) -> PlacedTrade | None:
|
28
31
|
buy_trades = [t for t in self.trades if t.trade_type == TradeType.BUY]
|
@@ -45,7 +48,7 @@ class ProcessMarketTrace(BaseModel):
|
|
45
48
|
market=market,
|
46
49
|
answer=answer,
|
47
50
|
trades=trades,
|
48
|
-
timestamp=trace.timestamp,
|
51
|
+
timestamp=int(trace.timestamp.timestamp()),
|
49
52
|
)
|
50
53
|
|
51
54
|
|
@@ -57,7 +60,7 @@ class ResolvedBetWithTrace(BaseModel):
|
|
57
60
|
def get_traces_for_agent(
|
58
61
|
agent_name: str,
|
59
62
|
trace_name: str,
|
60
|
-
from_timestamp:
|
63
|
+
from_timestamp: DatetimeUTC,
|
61
64
|
has_output: bool,
|
62
65
|
client: Langfuse,
|
63
66
|
) -> list[TraceWithDetails]:
|
@@ -115,7 +118,7 @@ def trace_to_trades(trace: TraceWithDetails) -> list[PlacedTrade]:
|
|
115
118
|
|
116
119
|
|
117
120
|
def get_closest_datetime_from_list(
|
118
|
-
ref_datetime:
|
121
|
+
ref_datetime: DatetimeUTC, datetimes: list[DatetimeUTC]
|
119
122
|
) -> int:
|
120
123
|
"""Get the index of the closest datetime to the reference datetime"""
|
121
124
|
if len(datetimes) == 1:
|
@@ -149,20 +152,22 @@ def get_trace_for_bet(
|
|
149
152
|
else:
|
150
153
|
# In-case there are multiple traces for the same market, get the closest
|
151
154
|
# trace to the bet
|
152
|
-
bet_timestamp = convert_to_utc_datetime(bet.created_time)
|
153
155
|
closest_trace_index = get_closest_datetime_from_list(
|
154
|
-
|
155
|
-
[t.
|
156
|
+
bet.created_time,
|
157
|
+
[t.timestamp_datetime for t in traces_for_bet],
|
156
158
|
)
|
157
159
|
|
158
160
|
# Sanity check: Let's say the upper bound for time between
|
159
161
|
# `agent.process_market` being called and the bet being placed is 20
|
160
162
|
# minutes
|
161
163
|
candidate_trace = traces_for_bet[closest_trace_index]
|
162
|
-
if
|
164
|
+
if (
|
165
|
+
abs(candidate_trace.timestamp_datetime - bet.created_time).total_seconds()
|
166
|
+
> 1200
|
167
|
+
):
|
163
168
|
logger.info(
|
164
169
|
f"Closest trace to bet has timestamp {candidate_trace.timestamp}, "
|
165
|
-
f"but bet was created at {
|
170
|
+
f"but bet was created at {bet.created_time}. Not matching"
|
166
171
|
)
|
167
172
|
return None
|
168
173
|
|
@@ -1,8 +1,7 @@
|
|
1
1
|
import typing as t
|
2
|
-
from datetime import
|
2
|
+
from datetime import timedelta
|
3
3
|
|
4
4
|
import tenacity
|
5
|
-
from loguru import logger
|
6
5
|
from pydantic import BaseModel
|
7
6
|
from sqlalchemy import Column
|
8
7
|
from sqlalchemy.dialects.postgresql import JSONB
|
@@ -18,7 +17,8 @@ from sqlmodel import (
|
|
18
17
|
)
|
19
18
|
|
20
19
|
from prediction_market_agent_tooling.config import APIKeys
|
21
|
-
from prediction_market_agent_tooling.
|
20
|
+
from prediction_market_agent_tooling.loggers import logger
|
21
|
+
from prediction_market_agent_tooling.tools.utils import DatetimeUTC, utcnow
|
22
22
|
|
23
23
|
|
24
24
|
class TavilyResult(BaseModel):
|
@@ -59,7 +59,7 @@ class TavilyResponseModel(SQLModel, table=True):
|
|
59
59
|
include_images: bool
|
60
60
|
use_cache: bool
|
61
61
|
# Datetime at the time of search response and response from the search
|
62
|
-
datetime_:
|
62
|
+
datetime_: DatetimeUTC = Field(index=True, nullable=False)
|
63
63
|
response: dict[str, t.Any] = Field(sa_column=Column(JSONB, nullable=False))
|
64
64
|
|
65
65
|
@staticmethod
|
@@ -89,7 +89,7 @@ class TavilyResponseModel(SQLModel, table=True):
|
|
89
89
|
include_raw_content=include_raw_content,
|
90
90
|
include_images=include_images,
|
91
91
|
use_cache=use_cache,
|
92
|
-
datetime_=
|
92
|
+
datetime_=utcnow(),
|
93
93
|
response=response.model_dump(),
|
94
94
|
)
|
95
95
|
|
@@ -1,20 +1,18 @@
|
|
1
1
|
import json
|
2
2
|
import os
|
3
3
|
import subprocess
|
4
|
-
import typing as t
|
5
4
|
from datetime import datetime
|
6
|
-
from typing import Any, NoReturn, Optional, Type, TypeVar
|
5
|
+
from typing import Any, NoReturn, Optional, Type, TypeVar
|
7
6
|
|
8
7
|
import pytz
|
9
8
|
import requests
|
10
9
|
from google.cloud import secretmanager
|
11
10
|
from pydantic import BaseModel, ValidationError
|
12
|
-
from pydantic.functional_validators import BeforeValidator
|
13
11
|
from scipy.optimize import newton
|
14
12
|
from scipy.stats import entropy
|
15
13
|
|
16
14
|
from prediction_market_agent_tooling.gtypes import (
|
17
|
-
|
15
|
+
DatetimeUTC,
|
18
16
|
PrivateKey,
|
19
17
|
Probability,
|
20
18
|
SecretStr,
|
@@ -85,55 +83,33 @@ def export_requirements_from_toml(output_dir: str) -> None:
|
|
85
83
|
logger.debug(f"Saved requirements to {output_dir}/requirements.txt")
|
86
84
|
|
87
85
|
|
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
|
-
def utc_timestamp_to_utc_datetime(ts: int) -> DatetimeWithTimezone:
|
114
|
-
...
|
115
|
-
|
116
|
-
|
117
|
-
@t.overload
|
118
|
-
def utc_timestamp_to_utc_datetime(ts: None) -> None:
|
119
|
-
...
|
120
|
-
|
121
|
-
|
122
|
-
def utc_timestamp_to_utc_datetime(ts: int | None) -> DatetimeWithTimezone | None:
|
123
|
-
return (
|
124
|
-
convert_to_utc_datetime(datetime.fromtimestamp(ts, tz=pytz.UTC))
|
125
|
-
if ts is not None
|
126
|
-
else None
|
86
|
+
def utcnow() -> DatetimeUTC:
|
87
|
+
return DatetimeUTC.from_datetime(datetime.now(pytz.UTC))
|
88
|
+
|
89
|
+
|
90
|
+
def utc_datetime(
|
91
|
+
year: int,
|
92
|
+
month: int,
|
93
|
+
day: int,
|
94
|
+
hour: int = 0,
|
95
|
+
minute: int = 0,
|
96
|
+
second: int = 0,
|
97
|
+
microsecond: int = 0,
|
98
|
+
*,
|
99
|
+
fold: int = 0,
|
100
|
+
) -> DatetimeUTC:
|
101
|
+
dt = datetime(
|
102
|
+
year=year,
|
103
|
+
month=month,
|
104
|
+
day=day,
|
105
|
+
hour=hour,
|
106
|
+
minute=minute,
|
107
|
+
second=second,
|
108
|
+
microsecond=microsecond,
|
109
|
+
tzinfo=pytz.UTC,
|
110
|
+
fold=fold,
|
127
111
|
)
|
128
|
-
|
129
|
-
|
130
|
-
UTCDatetimeFromUTCTimestamp = t.Annotated[
|
131
|
-
datetime, BeforeValidator(utc_timestamp_to_utc_datetime)
|
132
|
-
]
|
133
|
-
|
134
|
-
|
135
|
-
def utcnow() -> DatetimeWithTimezone:
|
136
|
-
return convert_to_utc_datetime(datetime.now(pytz.UTC))
|
112
|
+
return DatetimeUTC.from_datetime(dt)
|
137
113
|
|
138
114
|
|
139
115
|
def get_current_git_commit_sha() -> str:
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: prediction-market-agent-tooling
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.50.0
|
4
4
|
Summary: Tools to benchmark, deploy and monitor prediction market agents.
|
5
5
|
Author: Gnosis
|
6
6
|
Requires-Python: >=3.10,<3.12
|
@@ -20,6 +20,7 @@ Requires-Dist: google-api-python-client (==2.95.0) ; extra == "google"
|
|
20
20
|
Requires-Dist: google-cloud-functions (>=1.16.0,<2.0.0)
|
21
21
|
Requires-Dist: google-cloud-resource-manager (>=1.12.0,<2.0.0)
|
22
22
|
Requires-Dist: google-cloud-secret-manager (>=2.18.2,<3.0.0)
|
23
|
+
Requires-Dist: hishel (>=0.0.31,<0.0.32)
|
23
24
|
Requires-Dist: isort (>=5.13.2,<6.0.0)
|
24
25
|
Requires-Dist: langchain (>=0.2.6,<0.3.0) ; extra == "langchain"
|
25
26
|
Requires-Dist: langchain-community (>=0.0.19)
|
@@ -35,16 +36,18 @@ Requires-Dist: psycopg2-binary (>=2.9.9,<3.0.0)
|
|
35
36
|
Requires-Dist: pydantic (>=2.6.1,<3.0.0)
|
36
37
|
Requires-Dist: pydantic-settings (>=2.4.0,<3.0.0)
|
37
38
|
Requires-Dist: pymongo (>=4.8.0,<5.0.0)
|
39
|
+
Requires-Dist: python-dateutil (>=2.9.0.post0,<3.0.0)
|
38
40
|
Requires-Dist: safe-cli (>=1.0.0,<2.0.0)
|
39
41
|
Requires-Dist: safe-eth-py (>=6.0.0b14,<7.0.0)
|
40
42
|
Requires-Dist: scikit-learn (>=1.3.1,<2.0.0)
|
41
|
-
Requires-Dist: sqlmodel (>=0.0.
|
43
|
+
Requires-Dist: sqlmodel (>=0.0.22,<0.0.23)
|
42
44
|
Requires-Dist: streamlit (>=1.31.0,<2.0.0)
|
43
45
|
Requires-Dist: subgrounds (>=1.9.1,<2.0.0)
|
44
46
|
Requires-Dist: tabulate (>=0.9.0,<0.10.0)
|
45
47
|
Requires-Dist: tavily-python (>=0.3.9,<0.4.0)
|
46
48
|
Requires-Dist: tqdm (>=4.66.2,<5.0.0)
|
47
49
|
Requires-Dist: typer (>=0.9.0,<1.0.0)
|
50
|
+
Requires-Dist: types-python-dateutil (>=2.9.0.20240906,<3.0.0.0)
|
48
51
|
Requires-Dist: types-pytz (>=2024.1.0.20240203,<2025.0.0.0)
|
49
52
|
Requires-Dist: types-requests (>=2.31.0.0,<3.0.0.0)
|
50
53
|
Requires-Dist: web3 (>=6.15.1,<7.0.0)
|