prediction-market-agent-tooling 0.57.0__py3-none-any.whl → 0.57.2__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/config.py +2 -2
- prediction_market_agent_tooling/markets/base_subgraph_handler.py +2 -2
- prediction_market_agent_tooling/markets/data_models.py +14 -1
- prediction_market_agent_tooling/markets/omen/data_models.py +25 -7
- prediction_market_agent_tooling/markets/omen/omen.py +4 -0
- prediction_market_agent_tooling/markets/omen/omen_contracts.py +1 -1
- prediction_market_agent_tooling/markets/omen/omen_subgraph_handler.py +38 -3
- prediction_market_agent_tooling/monitor/financial_metrics/financial_metrics.py +5 -3
- prediction_market_agent_tooling/monitor/monitor.py +1 -1
- prediction_market_agent_tooling/tools/caches/db_cache.py +9 -73
- prediction_market_agent_tooling/tools/caches/inmemory_cache.py +44 -4
- prediction_market_agent_tooling/tools/caches/serializers.py +61 -0
- prediction_market_agent_tooling/tools/db/db_manager.py +76 -0
- prediction_market_agent_tooling/tools/httpx_cached_client.py +4 -1
- prediction_market_agent_tooling/tools/langfuse_client_utils.py +2 -0
- prediction_market_agent_tooling/tools/relevant_news_analysis/relevant_news_cache.py +7 -17
- prediction_market_agent_tooling/tools/transaction_cache.py +2 -2
- {prediction_market_agent_tooling-0.57.0.dist-info → prediction_market_agent_tooling-0.57.2.dist-info}/METADATA +3 -1
- {prediction_market_agent_tooling-0.57.0.dist-info → prediction_market_agent_tooling-0.57.2.dist-info}/RECORD +22 -20
- {prediction_market_agent_tooling-0.57.0.dist-info → prediction_market_agent_tooling-0.57.2.dist-info}/LICENSE +0 -0
- {prediction_market_agent_tooling-0.57.0.dist-info → prediction_market_agent_tooling-0.57.2.dist-info}/WHEEL +0 -0
- {prediction_market_agent_tooling-0.57.0.dist-info → prediction_market_agent_tooling-0.57.2.dist-info}/entry_points.txt +0 -0
@@ -188,14 +188,14 @@ class APIKeys(BaseSettings):
|
|
188
188
|
return {
|
189
189
|
k: v
|
190
190
|
for k, v in self.model_dump().items()
|
191
|
-
if
|
191
|
+
if self.model_fields[k].annotation not in SECRET_TYPES and v is not None
|
192
192
|
}
|
193
193
|
|
194
194
|
def model_dump_secrets(self) -> dict[str, t.Any]:
|
195
195
|
return {
|
196
196
|
k: v.get_secret_value() if isinstance(v, SecretStr) else v
|
197
197
|
for k, v in self.model_dump().items()
|
198
|
-
if
|
198
|
+
if self.model_fields[k].annotation in SECRET_TYPES and v is not None
|
199
199
|
}
|
200
200
|
|
201
201
|
def check_if_is_safe_owner(self, ethereum_client: EthereumClient) -> bool:
|
@@ -12,8 +12,8 @@ T = t.TypeVar("T", bound=BaseModel)
|
|
12
12
|
|
13
13
|
|
14
14
|
class BaseSubgraphHandler(metaclass=SingletonMeta):
|
15
|
-
def __init__(self) -> None:
|
16
|
-
self.sg = Subgrounds()
|
15
|
+
def __init__(self, timeout: int = 30) -> None:
|
16
|
+
self.sg = Subgrounds(timeout=timeout)
|
17
17
|
# Patch methods to retry on failure.
|
18
18
|
self.sg.query_json = tenacity.retry(
|
19
19
|
stop=tenacity.stop_after_attempt(3),
|
@@ -142,7 +142,7 @@ class PlacedTrade(Trade):
|
|
142
142
|
)
|
143
143
|
|
144
144
|
|
145
|
-
class
|
145
|
+
class SimulatedBetDetail(BaseModel):
|
146
146
|
strategy: str
|
147
147
|
url: str
|
148
148
|
market_p_yes: float
|
@@ -161,3 +161,16 @@ class SharpeOutput(BaseModel):
|
|
161
161
|
annualized_volatility: float
|
162
162
|
mean_daily_return: float
|
163
163
|
annualized_sharpe_ratio: float
|
164
|
+
|
165
|
+
|
166
|
+
class SimulatedLifetimeDetail(BaseModel):
|
167
|
+
p_yes_mse: float
|
168
|
+
total_bet_amount: float
|
169
|
+
total_bet_profit: float
|
170
|
+
total_simulated_amount: float
|
171
|
+
total_simulated_profit: float
|
172
|
+
roi: float
|
173
|
+
simulated_roi: float
|
174
|
+
sharpe_output_original: SharpeOutput
|
175
|
+
sharpe_output_simulation: SharpeOutput
|
176
|
+
maximize: float
|
@@ -42,6 +42,10 @@ PRESAGIO_BASE_URL = "https://presagio.pages.dev"
|
|
42
42
|
TEST_CATEGORY = "test" # This category is hidden on Presagio for testing purposes.
|
43
43
|
|
44
44
|
|
45
|
+
def construct_presagio_url(market_id: HexAddress) -> str:
|
46
|
+
return f"{PRESAGIO_BASE_URL}/markets?id={market_id}"
|
47
|
+
|
48
|
+
|
45
49
|
def get_boolean_outcome(outcome_str: str) -> bool:
|
46
50
|
if outcome_str == OMEN_TRUE_OUTCOME:
|
47
51
|
return True
|
@@ -392,7 +396,7 @@ class OmenMarket(BaseModel):
|
|
392
396
|
|
393
397
|
@property
|
394
398
|
def url(self) -> str:
|
395
|
-
return
|
399
|
+
return construct_presagio_url(self.id)
|
396
400
|
|
397
401
|
@staticmethod
|
398
402
|
def from_created_market(model: "CreatedMarket") -> "OmenMarket":
|
@@ -499,13 +503,17 @@ class OmenBet(BaseModel):
|
|
499
503
|
creator: OmenBetCreator
|
500
504
|
creationTimestamp: int
|
501
505
|
collateralAmount: Wei
|
502
|
-
collateralAmountUSD: USD
|
503
506
|
feeAmount: Wei
|
504
507
|
outcomeIndex: int
|
505
508
|
outcomeTokensTraded: Wei
|
506
509
|
transactionHash: HexBytes
|
507
510
|
fpmm: OmenMarket
|
508
511
|
|
512
|
+
@property
|
513
|
+
def collateral_amount_usd(self) -> USD:
|
514
|
+
# Convert manually instad of using the field `collateralAmountUSD` available on the graph, because it's bugged, it's 0 for non-xDai markets.
|
515
|
+
return USD(wei_to_xdai(self.collateralAmount))
|
516
|
+
|
509
517
|
@property
|
510
518
|
def creation_datetime(self) -> DatetimeUTC:
|
511
519
|
return DatetimeUTC.to_datetime_utc(self.creationTimestamp)
|
@@ -540,7 +548,7 @@ class OmenBet(BaseModel):
|
|
540
548
|
return Bet(
|
541
549
|
id=str(self.transactionHash),
|
542
550
|
# Use the transaction hash instead of the bet id - both are valid, but we return the transaction hash from the trade functions, so be consistent here.
|
543
|
-
amount=BetAmount(amount=self.
|
551
|
+
amount=BetAmount(amount=self.collateral_amount_usd, currency=Currency.xDai),
|
544
552
|
outcome=self.boolean_outcome,
|
545
553
|
created_time=self.creation_datetime,
|
546
554
|
market_question=self.title,
|
@@ -556,7 +564,7 @@ class OmenBet(BaseModel):
|
|
556
564
|
return ResolvedBet(
|
557
565
|
id=self.transactionHash.hex(),
|
558
566
|
# Use the transaction hash instead of the bet id - both are valid, but we return the transaction hash from the trade functions, so be consistent here.
|
559
|
-
amount=BetAmount(amount=self.
|
567
|
+
amount=BetAmount(amount=self.collateral_amount_usd, currency=Currency.xDai),
|
560
568
|
outcome=self.boolean_outcome,
|
561
569
|
created_time=self.creation_datetime,
|
562
570
|
market_question=self.title,
|
@@ -775,6 +783,12 @@ class CreatedMarket(BaseModel):
|
|
775
783
|
fee: Wei
|
776
784
|
distribution_hint: list[OmenOutcomeToken] | None
|
777
785
|
|
786
|
+
@property
|
787
|
+
def url(self) -> str:
|
788
|
+
return construct_presagio_url(
|
789
|
+
self.market_event.fixed_product_market_maker_checksummed
|
790
|
+
)
|
791
|
+
|
778
792
|
|
779
793
|
class ContractPrediction(BaseModel):
|
780
794
|
model_config = ConfigDict(populate_by_name=True)
|
@@ -797,9 +811,13 @@ class ContractPrediction(BaseModel):
|
|
797
811
|
return Web3.to_checksum_address(self.publisher)
|
798
812
|
|
799
813
|
@staticmethod
|
800
|
-
def from_tuple(values: tuple[t.Any]) -> "ContractPrediction":
|
801
|
-
|
802
|
-
|
814
|
+
def from_tuple(values: tuple[t.Any, ...]) -> "ContractPrediction":
|
815
|
+
return ContractPrediction(
|
816
|
+
publisher=values[0],
|
817
|
+
ipfs_hash=values[1],
|
818
|
+
tx_hashes=values[2],
|
819
|
+
estimated_probability_bps=values[3],
|
820
|
+
)
|
803
821
|
|
804
822
|
|
805
823
|
class IPFSAgentResult(BaseModel):
|
@@ -480,6 +480,8 @@ class OmenAgentMarket(AgentMarket):
|
|
480
480
|
better_address: ChecksumAddress,
|
481
481
|
start_time: DatetimeUTC,
|
482
482
|
end_time: DatetimeUTC | None,
|
483
|
+
market_resolved_before: DatetimeUTC | None = None,
|
484
|
+
market_resolved_after: DatetimeUTC | None = None,
|
483
485
|
) -> list[ResolvedBet]:
|
484
486
|
subgraph_handler = OmenSubgraphHandler()
|
485
487
|
bets = subgraph_handler.get_resolved_bets_with_valid_answer(
|
@@ -487,6 +489,8 @@ class OmenAgentMarket(AgentMarket):
|
|
487
489
|
start_time=start_time,
|
488
490
|
end_time=end_time,
|
489
491
|
market_id=None,
|
492
|
+
market_resolved_before=market_resolved_before,
|
493
|
+
market_resolved_after=market_resolved_after,
|
490
494
|
)
|
491
495
|
generic_bets = [b.to_generic_resolved_bet() for b in bets]
|
492
496
|
return generic_bets
|
@@ -538,7 +538,7 @@ class OmenKlerosContract(ContractOnGnosisChain):
|
|
538
538
|
address = "0xe40DD83a262da3f56976038F1554Fe541Fa75ecd"
|
539
539
|
|
540
540
|
elif arbitrator == Arbitrator.KLEROS_31_JURORS_WITH_APPEAL:
|
541
|
-
address = "
|
541
|
+
address = "0x5562Ac605764DC4039fb6aB56a74f7321396Cdf2"
|
542
542
|
|
543
543
|
else:
|
544
544
|
raise ValueError(f"Unsupported arbitrator: {arbitrator=}")
|
@@ -33,6 +33,9 @@ from prediction_market_agent_tooling.markets.omen.omen_contracts import (
|
|
33
33
|
WrappedxDaiContract,
|
34
34
|
sDaiContract,
|
35
35
|
)
|
36
|
+
from prediction_market_agent_tooling.tools.caches.inmemory_cache import (
|
37
|
+
persistent_inmemory_cache,
|
38
|
+
)
|
36
39
|
from prediction_market_agent_tooling.tools.utils import (
|
37
40
|
DatetimeUTC,
|
38
41
|
to_int_timestamp,
|
@@ -112,7 +115,6 @@ class OmenSubgraphHandler(BaseSubgraphHandler):
|
|
112
115
|
bets_field.creator.id,
|
113
116
|
bets_field.creationTimestamp,
|
114
117
|
bets_field.collateralAmount,
|
115
|
-
bets_field.collateralAmountUSD,
|
116
118
|
bets_field.feeAmount,
|
117
119
|
bets_field.outcomeIndex,
|
118
120
|
bets_field.outcomeTokensTraded,
|
@@ -524,6 +526,8 @@ class OmenSubgraphHandler(BaseSubgraphHandler):
|
|
524
526
|
filter_by_answer_finalized_not_null: bool = False,
|
525
527
|
type_: t.Literal["Buy", "Sell"] | None = None,
|
526
528
|
market_opening_after: DatetimeUTC | None = None,
|
529
|
+
market_resolved_before: DatetimeUTC | None = None,
|
530
|
+
market_resolved_after: DatetimeUTC | None = None,
|
527
531
|
collateral_amount_more_than: Wei | None = None,
|
528
532
|
sort_by_field: FieldPath | None = None,
|
529
533
|
sort_direction: str | None = None,
|
@@ -549,6 +553,15 @@ class OmenSubgraphHandler(BaseSubgraphHandler):
|
|
549
553
|
where_stms.append(
|
550
554
|
trade.fpmm.openingTimestamp > to_int_timestamp(market_opening_after)
|
551
555
|
)
|
556
|
+
if market_resolved_after is not None:
|
557
|
+
where_stms.append(
|
558
|
+
trade.fpmm.resolutionTimestamp > to_int_timestamp(market_resolved_after)
|
559
|
+
)
|
560
|
+
if market_resolved_before is not None:
|
561
|
+
where_stms.append(
|
562
|
+
trade.fpmm.resolutionTimestamp
|
563
|
+
< to_int_timestamp(market_resolved_before)
|
564
|
+
)
|
552
565
|
if collateral_amount_more_than is not None:
|
553
566
|
where_stms.append(trade.collateralAmount > collateral_amount_more_than)
|
554
567
|
|
@@ -577,6 +590,8 @@ class OmenSubgraphHandler(BaseSubgraphHandler):
|
|
577
590
|
market_id: t.Optional[ChecksumAddress] = None,
|
578
591
|
filter_by_answer_finalized_not_null: bool = False,
|
579
592
|
market_opening_after: DatetimeUTC | None = None,
|
593
|
+
market_resolved_before: DatetimeUTC | None = None,
|
594
|
+
market_resolved_after: DatetimeUTC | None = None,
|
580
595
|
collateral_amount_more_than: Wei | None = None,
|
581
596
|
) -> list[OmenBet]:
|
582
597
|
return self.get_trades(
|
@@ -587,15 +602,19 @@ class OmenSubgraphHandler(BaseSubgraphHandler):
|
|
587
602
|
filter_by_answer_finalized_not_null=filter_by_answer_finalized_not_null,
|
588
603
|
type_="Buy", # We consider `bet` to be only the `Buy` trade types.
|
589
604
|
market_opening_after=market_opening_after,
|
605
|
+
market_resolved_before=market_resolved_before,
|
606
|
+
market_resolved_after=market_resolved_after,
|
590
607
|
collateral_amount_more_than=collateral_amount_more_than,
|
591
608
|
)
|
592
609
|
|
593
610
|
def get_resolved_bets(
|
594
611
|
self,
|
595
612
|
better_address: ChecksumAddress,
|
596
|
-
start_time: DatetimeUTC,
|
613
|
+
start_time: DatetimeUTC | None = None,
|
597
614
|
end_time: t.Optional[DatetimeUTC] = None,
|
598
615
|
market_id: t.Optional[ChecksumAddress] = None,
|
616
|
+
market_resolved_before: DatetimeUTC | None = None,
|
617
|
+
market_resolved_after: DatetimeUTC | None = None,
|
599
618
|
) -> list[OmenBet]:
|
600
619
|
omen_bets = self.get_bets(
|
601
620
|
better_address=better_address,
|
@@ -603,14 +622,18 @@ class OmenSubgraphHandler(BaseSubgraphHandler):
|
|
603
622
|
end_time=end_time,
|
604
623
|
market_id=market_id,
|
605
624
|
filter_by_answer_finalized_not_null=True,
|
625
|
+
market_resolved_before=market_resolved_before,
|
626
|
+
market_resolved_after=market_resolved_after,
|
606
627
|
)
|
607
628
|
return [b for b in omen_bets if b.fpmm.is_resolved]
|
608
629
|
|
609
630
|
def get_resolved_bets_with_valid_answer(
|
610
631
|
self,
|
611
632
|
better_address: ChecksumAddress,
|
612
|
-
start_time: DatetimeUTC,
|
633
|
+
start_time: DatetimeUTC | None = None,
|
613
634
|
end_time: t.Optional[DatetimeUTC] = None,
|
635
|
+
market_resolved_before: DatetimeUTC | None = None,
|
636
|
+
market_resolved_after: DatetimeUTC | None = None,
|
614
637
|
market_id: t.Optional[ChecksumAddress] = None,
|
615
638
|
) -> list[OmenBet]:
|
616
639
|
bets = self.get_resolved_bets(
|
@@ -618,6 +641,8 @@ class OmenSubgraphHandler(BaseSubgraphHandler):
|
|
618
641
|
start_time=start_time,
|
619
642
|
end_time=end_time,
|
620
643
|
market_id=market_id,
|
644
|
+
market_resolved_before=market_resolved_before,
|
645
|
+
market_resolved_after=market_resolved_after,
|
621
646
|
)
|
622
647
|
return [b for b in bets if b.fpmm.is_resolved_with_valid_answer]
|
623
648
|
|
@@ -926,3 +951,13 @@ class OmenSubgraphHandler(BaseSubgraphHandler):
|
|
926
951
|
raise RuntimeError("Multiple results found for a single bet.")
|
927
952
|
|
928
953
|
return results[0]
|
954
|
+
|
955
|
+
|
956
|
+
@persistent_inmemory_cache
|
957
|
+
def get_omen_market_by_market_id_cached(
|
958
|
+
market_id: HexAddress,
|
959
|
+
block_number: int, # Force `block_number` to be provided, because `latest` block constantly updates.
|
960
|
+
) -> OmenMarket:
|
961
|
+
return OmenSubgraphHandler().get_omen_market_by_market_id(
|
962
|
+
market_id, block_number=block_number
|
963
|
+
)
|
@@ -3,13 +3,13 @@ import pandas as pd
|
|
3
3
|
|
4
4
|
from prediction_market_agent_tooling.markets.data_models import (
|
5
5
|
SharpeOutput,
|
6
|
-
|
6
|
+
SimulatedBetDetail,
|
7
7
|
)
|
8
8
|
|
9
9
|
|
10
10
|
class SharpeRatioCalculator:
|
11
11
|
def __init__(
|
12
|
-
self, details: list[
|
12
|
+
self, details: list[SimulatedBetDetail], risk_free_rate: float = 0.0
|
13
13
|
) -> None:
|
14
14
|
self.details = details
|
15
15
|
self.df = pd.DataFrame([d.model_dump() for d in self.details])
|
@@ -19,7 +19,9 @@ class SharpeRatioCalculator:
|
|
19
19
|
self, required_columns: list[str]
|
20
20
|
) -> None:
|
21
21
|
if not set(required_columns).issubset(self.df.columns):
|
22
|
-
raise ValueError(
|
22
|
+
raise ValueError(
|
23
|
+
f"Dataframe doesn't contain all the required columns. {required_columns=} {self.df.columns=}"
|
24
|
+
)
|
23
25
|
|
24
26
|
def prepare_wallet_daily_balance_df(
|
25
27
|
self, timestamp_col_name: str, profit_col_name: str
|
@@ -223,7 +223,7 @@ def monitor_agent(agent: DeployedAgent) -> None:
|
|
223
223
|
)
|
224
224
|
.interactive()
|
225
225
|
)
|
226
|
-
st.altair_chart(
|
226
|
+
st.altair_chart(
|
227
227
|
per_day_accuracy_chart.mark_line()
|
228
228
|
+ per_day_accuracy_chart.transform_loess("x-axis-day", "Is Correct").mark_line(
|
229
229
|
color="red", strokeDash=[5, 5]
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import hashlib
|
2
2
|
import inspect
|
3
3
|
import json
|
4
|
-
from datetime import
|
4
|
+
from datetime import timedelta
|
5
5
|
from functools import wraps
|
6
6
|
from typing import (
|
7
7
|
Any,
|
@@ -17,11 +17,12 @@ from typing import (
|
|
17
17
|
from pydantic import BaseModel
|
18
18
|
from sqlalchemy import Column
|
19
19
|
from sqlalchemy.dialects.postgresql import JSONB
|
20
|
-
from sqlmodel import Field,
|
20
|
+
from sqlmodel import Field, SQLModel, desc, select
|
21
21
|
|
22
22
|
from prediction_market_agent_tooling.config import APIKeys
|
23
23
|
from prediction_market_agent_tooling.loggers import logger
|
24
24
|
from prediction_market_agent_tooling.tools.datetime_utc import DatetimeUTC
|
25
|
+
from prediction_market_agent_tooling.tools.db.db_manager import DBManager
|
25
26
|
from prediction_market_agent_tooling.tools.utils import utcnow
|
26
27
|
|
27
28
|
FunctionT = TypeVar("FunctionT", bound=Callable[..., Any])
|
@@ -97,16 +98,7 @@ def db_cache(
|
|
97
98
|
if not api_keys.ENABLE_CACHE:
|
98
99
|
return func(*args, **kwargs)
|
99
100
|
|
100
|
-
|
101
|
-
api_keys.sqlalchemy_db_url.get_secret_value(),
|
102
|
-
# Use custom json serializer and deserializer, because otherwise, for example `datetime` serialization would fail.
|
103
|
-
json_serializer=json_serializer,
|
104
|
-
json_deserializer=json_deserializer,
|
105
|
-
pool_size=1,
|
106
|
-
)
|
107
|
-
|
108
|
-
# Create table if it doesn't exist
|
109
|
-
SQLModel.metadata.create_all(engine)
|
101
|
+
DBManager(api_keys).create_tables([FunctionCache])
|
110
102
|
|
111
103
|
# Convert *args and **kwargs to a single dictionary, where we have names for arguments passed as args as well.
|
112
104
|
signature = inspect.signature(func)
|
@@ -147,12 +139,11 @@ def db_cache(
|
|
147
139
|
|
148
140
|
# Determine if the function returns or contains Pydantic BaseModel(s)
|
149
141
|
return_type = func.__annotations__.get("return", None)
|
150
|
-
is_pydantic_model =
|
151
|
-
|
152
|
-
|
153
|
-
is_pydantic_model = True
|
142
|
+
is_pydantic_model = return_type is not None and contains_pydantic_model(
|
143
|
+
return_type
|
144
|
+
)
|
154
145
|
|
155
|
-
with
|
146
|
+
with DBManager(api_keys).get_session() as session:
|
156
147
|
# Try to get cached result
|
157
148
|
statement = (
|
158
149
|
select(FunctionCache)
|
@@ -205,12 +196,11 @@ def db_cache(
|
|
205
196
|
result=computed_result,
|
206
197
|
created_at=utcnow(),
|
207
198
|
)
|
208
|
-
with
|
199
|
+
with DBManager(api_keys).get_session() as session:
|
209
200
|
logger.info(f"Saving {cache_entry} into database.")
|
210
201
|
session.add(cache_entry)
|
211
202
|
session.commit()
|
212
203
|
|
213
|
-
engine.dispose()
|
214
204
|
return computed_result
|
215
205
|
|
216
206
|
return cast(FunctionT, wrapper)
|
@@ -230,60 +220,6 @@ def contains_pydantic_model(return_type: Any) -> bool:
|
|
230
220
|
return False
|
231
221
|
|
232
222
|
|
233
|
-
def json_serializer_default_fn(
|
234
|
-
y: DatetimeUTC | timedelta | date | BaseModel,
|
235
|
-
) -> str | dict[str, Any]:
|
236
|
-
"""
|
237
|
-
Used to serialize objects that don't support it by default into a specific string that can be deserialized out later.
|
238
|
-
If this function returns a dictionary, it will be called recursivelly.
|
239
|
-
If you add something here, also add it to `replace_custom_stringified_objects` below.
|
240
|
-
"""
|
241
|
-
if isinstance(y, DatetimeUTC):
|
242
|
-
return f"DatetimeUTC::{y.isoformat()}"
|
243
|
-
elif isinstance(y, timedelta):
|
244
|
-
return f"timedelta::{y.total_seconds()}"
|
245
|
-
elif isinstance(y, date):
|
246
|
-
return f"date::{y.isoformat()}"
|
247
|
-
elif isinstance(y, BaseModel):
|
248
|
-
return y.model_dump()
|
249
|
-
raise TypeError(
|
250
|
-
f"Unsuported type for the default json serialize function, value is {y}."
|
251
|
-
)
|
252
|
-
|
253
|
-
|
254
|
-
def json_serializer(x: Any) -> str:
|
255
|
-
return json.dumps(x, default=json_serializer_default_fn)
|
256
|
-
|
257
|
-
|
258
|
-
def replace_custom_stringified_objects(obj: Any) -> Any:
|
259
|
-
"""
|
260
|
-
Used to deserialize objects from `json_serializer_default_fn` into their proper form.
|
261
|
-
"""
|
262
|
-
if isinstance(obj, str):
|
263
|
-
if obj.startswith("DatetimeUTC::"):
|
264
|
-
iso_str = obj[len("DatetimeUTC::") :]
|
265
|
-
return DatetimeUTC.to_datetime_utc(iso_str)
|
266
|
-
elif obj.startswith("timedelta::"):
|
267
|
-
total_seconds_str = obj[len("timedelta::") :]
|
268
|
-
return timedelta(seconds=float(total_seconds_str))
|
269
|
-
elif obj.startswith("date::"):
|
270
|
-
iso_str = obj[len("date::") :]
|
271
|
-
return date.fromisoformat(iso_str)
|
272
|
-
else:
|
273
|
-
return obj
|
274
|
-
elif isinstance(obj, dict):
|
275
|
-
return {k: replace_custom_stringified_objects(v) for k, v in obj.items()}
|
276
|
-
elif isinstance(obj, list):
|
277
|
-
return [replace_custom_stringified_objects(item) for item in obj]
|
278
|
-
else:
|
279
|
-
return obj
|
280
|
-
|
281
|
-
|
282
|
-
def json_deserializer(s: str) -> Any:
|
283
|
-
data = json.loads(s)
|
284
|
-
return replace_custom_stringified_objects(data)
|
285
|
-
|
286
|
-
|
287
223
|
def convert_cached_output_to_pydantic(return_type: Any, data: Any) -> Any:
|
288
224
|
"""
|
289
225
|
Used to initialize Pydantic models from anything cached that was originally a Pydantic model in the output. Including models in nested structures.
|
@@ -1,5 +1,5 @@
|
|
1
1
|
from functools import cache
|
2
|
-
from typing import Any, Callable, TypeVar, cast
|
2
|
+
from typing import Any, Callable, TypeVar, cast, overload
|
3
3
|
|
4
4
|
from joblib import Memory
|
5
5
|
|
@@ -7,11 +7,51 @@ from prediction_market_agent_tooling.config import APIKeys
|
|
7
7
|
|
8
8
|
MEMORY = Memory(APIKeys().CACHE_DIR, verbose=0)
|
9
9
|
|
10
|
+
|
10
11
|
T = TypeVar("T", bound=Callable[..., Any])
|
11
12
|
|
12
13
|
|
13
|
-
|
14
|
+
@overload
|
15
|
+
def persistent_inmemory_cache(
|
16
|
+
func: None = None,
|
17
|
+
*,
|
18
|
+
in_memory_cache: bool = True,
|
19
|
+
) -> Callable[[T], T]:
|
20
|
+
...
|
21
|
+
|
22
|
+
|
23
|
+
@overload
|
24
|
+
def persistent_inmemory_cache(
|
25
|
+
func: T,
|
26
|
+
*,
|
27
|
+
in_memory_cache: bool = True,
|
28
|
+
) -> T:
|
29
|
+
...
|
30
|
+
|
31
|
+
|
32
|
+
def persistent_inmemory_cache(
|
33
|
+
func: T | None = None,
|
34
|
+
*,
|
35
|
+
in_memory_cache: bool = True,
|
36
|
+
) -> T | Callable[[T], T]:
|
14
37
|
"""
|
15
|
-
Wraps a function with both file cache (for persistent cache) and in-memory cache (for speed).
|
38
|
+
Wraps a function with both file cache (for persistent cache) and optional in-memory cache (for speed).
|
39
|
+
Can be used as @persistent_inmemory_cache or @persistent_inmemory_cache(in_memory_cache=False)
|
16
40
|
"""
|
17
|
-
|
41
|
+
if func is None:
|
42
|
+
# Ugly Pythonic way to support this decorator as `@persistent_inmemory_cache` but also `@persistent_inmemory_cache(in_memory_cache=False)`
|
43
|
+
def decorator(func: T) -> T:
|
44
|
+
return persistent_inmemory_cache(
|
45
|
+
func,
|
46
|
+
in_memory_cache=in_memory_cache,
|
47
|
+
)
|
48
|
+
|
49
|
+
return decorator
|
50
|
+
else:
|
51
|
+
# The decorator is called without arguments.
|
52
|
+
if not APIKeys().ENABLE_CACHE:
|
53
|
+
return func
|
54
|
+
cached_func = MEMORY.cache(func)
|
55
|
+
if in_memory_cache:
|
56
|
+
cached_func = cache(cached_func)
|
57
|
+
return cast(T, cached_func)
|
@@ -0,0 +1,61 @@
|
|
1
|
+
import json
|
2
|
+
import typing as t
|
3
|
+
from datetime import date, timedelta
|
4
|
+
|
5
|
+
from pydantic import BaseModel
|
6
|
+
|
7
|
+
from prediction_market_agent_tooling.tools.datetime_utc import DatetimeUTC
|
8
|
+
|
9
|
+
|
10
|
+
def json_serializer(x: t.Any) -> str:
|
11
|
+
return json.dumps(x, default=json_serializer_default_fn)
|
12
|
+
|
13
|
+
|
14
|
+
def json_serializer_default_fn(
|
15
|
+
y: DatetimeUTC | timedelta | date | BaseModel,
|
16
|
+
) -> str | dict[str, t.Any]:
|
17
|
+
"""
|
18
|
+
Used to serialize objects that don't support it by default into a specific string that can be deserialized out later.
|
19
|
+
If this function returns a dictionary, it will be called recursivelly.
|
20
|
+
If you add something here, also add it to `replace_custom_stringified_objects` below.
|
21
|
+
"""
|
22
|
+
if isinstance(y, DatetimeUTC):
|
23
|
+
return f"DatetimeUTC::{y.isoformat()}"
|
24
|
+
elif isinstance(y, timedelta):
|
25
|
+
return f"timedelta::{y.total_seconds()}"
|
26
|
+
elif isinstance(y, date):
|
27
|
+
return f"date::{y.isoformat()}"
|
28
|
+
elif isinstance(y, BaseModel):
|
29
|
+
return y.model_dump()
|
30
|
+
raise TypeError(
|
31
|
+
f"Unsuported type for the default json serialize function, value is {y}."
|
32
|
+
)
|
33
|
+
|
34
|
+
|
35
|
+
def json_deserializer(s: str) -> t.Any:
|
36
|
+
data = json.loads(s)
|
37
|
+
return replace_custom_stringified_objects(data)
|
38
|
+
|
39
|
+
|
40
|
+
def replace_custom_stringified_objects(obj: t.Any) -> t.Any:
|
41
|
+
"""
|
42
|
+
Used to deserialize objects from `json_serializer_default_fn` into their proper form.
|
43
|
+
"""
|
44
|
+
if isinstance(obj, str):
|
45
|
+
if obj.startswith("DatetimeUTC::"):
|
46
|
+
iso_str = obj[len("DatetimeUTC::") :]
|
47
|
+
return DatetimeUTC.to_datetime_utc(iso_str)
|
48
|
+
elif obj.startswith("timedelta::"):
|
49
|
+
total_seconds_str = obj[len("timedelta::") :]
|
50
|
+
return timedelta(seconds=float(total_seconds_str))
|
51
|
+
elif obj.startswith("date::"):
|
52
|
+
iso_str = obj[len("date::") :]
|
53
|
+
return date.fromisoformat(iso_str)
|
54
|
+
else:
|
55
|
+
return obj
|
56
|
+
elif isinstance(obj, dict):
|
57
|
+
return {k: replace_custom_stringified_objects(v) for k, v in obj.items()}
|
58
|
+
elif isinstance(obj, list):
|
59
|
+
return [replace_custom_stringified_objects(item) for item in obj]
|
60
|
+
else:
|
61
|
+
return obj
|
@@ -0,0 +1,76 @@
|
|
1
|
+
import hashlib
|
2
|
+
from contextlib import contextmanager
|
3
|
+
from typing import Generator, Sequence
|
4
|
+
|
5
|
+
from sqlalchemy import Connection
|
6
|
+
from sqlmodel import Session, SQLModel, create_engine
|
7
|
+
|
8
|
+
from prediction_market_agent_tooling.config import APIKeys
|
9
|
+
from prediction_market_agent_tooling.tools.caches.serializers import (
|
10
|
+
json_deserializer,
|
11
|
+
json_serializer,
|
12
|
+
)
|
13
|
+
|
14
|
+
|
15
|
+
class DBManager:
|
16
|
+
_instances: dict[str, "DBManager"] = {}
|
17
|
+
|
18
|
+
def __new__(cls, api_keys: APIKeys | None = None) -> "DBManager":
|
19
|
+
sqlalchemy_db_url = (api_keys or APIKeys()).sqlalchemy_db_url
|
20
|
+
# Hash the secret value to not store secrets in plain text.
|
21
|
+
url_hash = hashlib.md5(
|
22
|
+
sqlalchemy_db_url.get_secret_value().encode()
|
23
|
+
).hexdigest()
|
24
|
+
# Return singleton per database connection.
|
25
|
+
if url_hash not in cls._instances:
|
26
|
+
instance = super(DBManager, cls).__new__(cls)
|
27
|
+
cls._instances[url_hash] = instance
|
28
|
+
return cls._instances[url_hash]
|
29
|
+
|
30
|
+
def __init__(self, api_keys: APIKeys | None = None) -> None:
|
31
|
+
sqlalchemy_db_url = (api_keys or APIKeys()).sqlalchemy_db_url
|
32
|
+
self._engine = create_engine(
|
33
|
+
sqlalchemy_db_url.get_secret_value(),
|
34
|
+
json_serializer=json_serializer,
|
35
|
+
json_deserializer=json_deserializer,
|
36
|
+
pool_size=20,
|
37
|
+
pool_recycle=3600,
|
38
|
+
echo=True,
|
39
|
+
)
|
40
|
+
self.cache_table_initialized: dict[str, bool] = {}
|
41
|
+
|
42
|
+
@contextmanager
|
43
|
+
def get_session(self) -> Generator[Session, None, None]:
|
44
|
+
with Session(self._engine) as session:
|
45
|
+
yield session
|
46
|
+
|
47
|
+
@contextmanager
|
48
|
+
def get_connection(self) -> Generator[Connection, None, None]:
|
49
|
+
with self.get_session() as session:
|
50
|
+
yield session.connection()
|
51
|
+
|
52
|
+
def create_tables(
|
53
|
+
self, sqlmodel_tables: Sequence[type[SQLModel]] | None = None
|
54
|
+
) -> None:
|
55
|
+
# Determine tables to create
|
56
|
+
if sqlmodel_tables is not None:
|
57
|
+
tables_to_create = []
|
58
|
+
for sqlmodel_table in sqlmodel_tables:
|
59
|
+
table_name = (
|
60
|
+
sqlmodel_table.__tablename__()
|
61
|
+
if callable(sqlmodel_table.__tablename__)
|
62
|
+
else sqlmodel_table.__tablename__
|
63
|
+
)
|
64
|
+
table = SQLModel.metadata.tables[table_name]
|
65
|
+
if not self.cache_table_initialized.get(table.name):
|
66
|
+
tables_to_create.append(table)
|
67
|
+
else:
|
68
|
+
tables_to_create = None
|
69
|
+
|
70
|
+
# Create tables in the database
|
71
|
+
SQLModel.metadata.create_all(self._engine, tables=tables_to_create)
|
72
|
+
|
73
|
+
# Update cache to mark tables as initialized
|
74
|
+
if tables_to_create:
|
75
|
+
for table in tables_to_create:
|
76
|
+
self.cache_table_initialized[table.name] = True
|
@@ -3,7 +3,10 @@ import hishel
|
|
3
3
|
|
4
4
|
class HttpxCachedClient:
|
5
5
|
def __init__(self) -> None:
|
6
|
-
storage = hishel.FileStorage(
|
6
|
+
storage = hishel.FileStorage(
|
7
|
+
ttl=24 * 60 * 60,
|
8
|
+
check_ttl_every=1 * 60 * 60,
|
9
|
+
)
|
7
10
|
controller = hishel.Controller(force_cache=True)
|
8
11
|
self.client = hishel.CacheClient(storage=storage, controller=controller)
|
9
12
|
|
@@ -63,6 +63,7 @@ def get_traces_for_agent(
|
|
63
63
|
from_timestamp: DatetimeUTC,
|
64
64
|
has_output: bool,
|
65
65
|
client: Langfuse,
|
66
|
+
to_timestamp: DatetimeUTC | None = None,
|
66
67
|
) -> list[TraceWithDetails]:
|
67
68
|
"""
|
68
69
|
Fetch agent traces using pagination
|
@@ -76,6 +77,7 @@ def get_traces_for_agent(
|
|
76
77
|
limit=100,
|
77
78
|
page=page,
|
78
79
|
from_timestamp=from_timestamp,
|
80
|
+
to_timestamp=to_timestamp,
|
79
81
|
)
|
80
82
|
if not traces.data:
|
81
83
|
break
|
@@ -1,10 +1,11 @@
|
|
1
1
|
from datetime import datetime, timedelta
|
2
2
|
|
3
3
|
from pydantic import ValidationError
|
4
|
-
from sqlmodel import Field,
|
4
|
+
from sqlmodel import Field, SQLModel, desc, select
|
5
5
|
|
6
6
|
from prediction_market_agent_tooling.config import APIKeys
|
7
7
|
from prediction_market_agent_tooling.loggers import logger
|
8
|
+
from prediction_market_agent_tooling.tools.db.db_manager import DBManager
|
8
9
|
from prediction_market_agent_tooling.tools.relevant_news_analysis.data_models import (
|
9
10
|
NoRelevantNews,
|
10
11
|
RelevantNews,
|
@@ -23,33 +24,22 @@ class RelevantNewsCacheModel(SQLModel, table=True):
|
|
23
24
|
|
24
25
|
|
25
26
|
class RelevantNewsResponseCache:
|
26
|
-
def __init__(self,
|
27
|
-
self.
|
28
|
-
(
|
29
|
-
sqlalchemy_db_url
|
30
|
-
if sqlalchemy_db_url
|
31
|
-
else APIKeys().sqlalchemy_db_url.get_secret_value()
|
32
|
-
),
|
33
|
-
pool_size=1,
|
34
|
-
)
|
27
|
+
def __init__(self, api_keys: APIKeys | None = None):
|
28
|
+
self.db_manager = DBManager(api_keys)
|
35
29
|
self._initialize_db()
|
36
30
|
|
37
31
|
def _initialize_db(self) -> None:
|
38
32
|
"""
|
39
33
|
Creates the tables if they don't exist
|
40
34
|
"""
|
41
|
-
|
42
|
-
SQLModel.metadata.create_all(
|
43
|
-
conn,
|
44
|
-
tables=[SQLModel.metadata.tables[RelevantNewsCacheModel.__tablename__]],
|
45
|
-
)
|
35
|
+
self.db_manager.create_tables([RelevantNewsCacheModel])
|
46
36
|
|
47
37
|
def find(
|
48
38
|
self,
|
49
39
|
question: str,
|
50
40
|
days_ago: int,
|
51
41
|
) -> RelevantNews | NoRelevantNews | None:
|
52
|
-
with
|
42
|
+
with self.db_manager.get_session() as session:
|
53
43
|
query = (
|
54
44
|
select(RelevantNewsCacheModel)
|
55
45
|
.where(RelevantNewsCacheModel.question == question)
|
@@ -82,7 +72,7 @@ class RelevantNewsResponseCache:
|
|
82
72
|
days_ago: int,
|
83
73
|
relevant_news: RelevantNews | None,
|
84
74
|
) -> None:
|
85
|
-
with
|
75
|
+
with self.db_manager.get_session() as session:
|
86
76
|
cached = RelevantNewsCacheModel(
|
87
77
|
question=question,
|
88
78
|
days_ago=days_ago,
|
@@ -9,8 +9,8 @@ from prediction_market_agent_tooling.loggers import logger
|
|
9
9
|
|
10
10
|
class TransactionBlockCache:
|
11
11
|
def __init__(self, web3: Web3):
|
12
|
-
self.block_number_cache = dc.Cache("block_cache_dir")
|
13
|
-
self.block_timestamp_cache = dc.Cache("timestamp_cache_dir")
|
12
|
+
self.block_number_cache = dc.Cache(".cache/block_cache_dir")
|
13
|
+
self.block_timestamp_cache = dc.Cache(".cache/timestamp_cache_dir")
|
14
14
|
self.web3 = web3
|
15
15
|
|
16
16
|
@tenacity.retry(
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: prediction-market-agent-tooling
|
3
|
-
Version: 0.57.
|
3
|
+
Version: 0.57.2
|
4
4
|
Summary: Tools to benchmark, deploy and monitor prediction market agents.
|
5
5
|
Author: Gnosis
|
6
6
|
Requires-Python: >=3.10,<3.12
|
@@ -10,6 +10,7 @@ Classifier: Programming Language :: Python :: 3.11
|
|
10
10
|
Provides-Extra: google
|
11
11
|
Provides-Extra: langchain
|
12
12
|
Provides-Extra: openai
|
13
|
+
Provides-Extra: optuna
|
13
14
|
Requires-Dist: autoflake (>=2.2.1,<3.0.0)
|
14
15
|
Requires-Dist: base58 (>=1.0.2,<2.0)
|
15
16
|
Requires-Dist: cron-validator (>=1.0.8,<2.0.0)
|
@@ -30,6 +31,7 @@ Requires-Dist: loguru (>=0.7.2,<0.8.0)
|
|
30
31
|
Requires-Dist: loky (>=3.4.1,<4.0.0)
|
31
32
|
Requires-Dist: numpy (>=1.26.4,<2.0.0)
|
32
33
|
Requires-Dist: openai (>=1.0.0,<2.0.0) ; extra == "openai"
|
34
|
+
Requires-Dist: optuna (>=4.1.0,<5.0.0) ; extra == "optuna"
|
33
35
|
Requires-Dist: pinatapy-vourhey (>=0.2.0,<0.3.0)
|
34
36
|
Requires-Dist: prompt-toolkit (>=3.0.43,<4.0.0)
|
35
37
|
Requires-Dist: psycopg2-binary (>=2.9.9,<3.0.0)
|
@@ -16,7 +16,7 @@ prediction_market_agent_tooling/benchmark/__init__.py,sha256=47DEQpj8HBSa-_TImW-
|
|
16
16
|
prediction_market_agent_tooling/benchmark/agents.py,sha256=B1-uWdyeN4GGKMWGK_-CcAFJg1m9Y_XuaeIHPB29QR8,3971
|
17
17
|
prediction_market_agent_tooling/benchmark/benchmark.py,sha256=MqTiaaJ3cYiOLUVR7OyImLWxcEya3Rl5JyFYW-K0lwM,17097
|
18
18
|
prediction_market_agent_tooling/benchmark/utils.py,sha256=D0MfUkVZllmvcU0VOurk9tcKT7JTtwwOp-63zuCBVuc,2880
|
19
|
-
prediction_market_agent_tooling/config.py,sha256=
|
19
|
+
prediction_market_agent_tooling/config.py,sha256=Ffb1ftRiguAxa5cS0nXvKK01HomdqzFDCsp8rFd5taM,7553
|
20
20
|
prediction_market_agent_tooling/deploy/agent.py,sha256=58Ms6wFcRM3yhpdDVT-ohryZhHJNinn1Z4MdrmCMXvM,23627
|
21
21
|
prediction_market_agent_tooling/deploy/agent_example.py,sha256=dIIdZashExWk9tOdyDjw87AuUcGyM7jYxNChYrVK2dM,1001
|
22
22
|
prediction_market_agent_tooling/deploy/betting_strategy.py,sha256=kMrIE3wMv_IB6nJd_1DmDXDkEZhsXFOgyTd7JZ0gqHI,13068
|
@@ -31,9 +31,9 @@ prediction_market_agent_tooling/jobs/jobs_models.py,sha256=GOtsNm7URhzZM5fPY64r8
|
|
31
31
|
prediction_market_agent_tooling/jobs/omen/omen_jobs.py,sha256=N0_jGDyXQeVXXlYg4oA_pOfqIjscHsLQbr0pBwFGoRo,5178
|
32
32
|
prediction_market_agent_tooling/loggers.py,sha256=Am6HHXRNO545BO3l7Ue9Wb2TkYE1OK8KKhGbI3XypVU,3751
|
33
33
|
prediction_market_agent_tooling/markets/agent_market.py,sha256=W2ME57-CSAhrt8qm8-b5r7yLq-Sk7R_BZMaApvjhrUE,12901
|
34
|
-
prediction_market_agent_tooling/markets/base_subgraph_handler.py,sha256=
|
34
|
+
prediction_market_agent_tooling/markets/base_subgraph_handler.py,sha256=7RaYO_4qAmQ6ZGM8oPK2-CkiJfKmV9MxM-rJlduaecU,1971
|
35
35
|
prediction_market_agent_tooling/markets/categorize.py,sha256=jsoHWvZk9pU6n17oWSCcCxNNYVwlb_NXsZxKRI7vmsk,1301
|
36
|
-
prediction_market_agent_tooling/markets/data_models.py,sha256=
|
36
|
+
prediction_market_agent_tooling/markets/data_models.py,sha256=oMoHxxiNekGgXX1FFExS_MNuHjte2pV1OEynVDIKVc8,4368
|
37
37
|
prediction_market_agent_tooling/markets/manifold/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
38
38
|
prediction_market_agent_tooling/markets/manifold/api.py,sha256=Fd0HYnstvvHO6AZkp1xiRlvCwQUc8kLR8DAj6PAZu0s,7297
|
39
39
|
prediction_market_agent_tooling/markets/manifold/data_models.py,sha256=eiGS4rEkxseZNpEb2BICKnjF0qqgkQTMuUPbSe7_04I,6059
|
@@ -45,11 +45,11 @@ prediction_market_agent_tooling/markets/metaculus/api.py,sha256=4TRPGytQQbSdf42D
|
|
45
45
|
prediction_market_agent_tooling/markets/metaculus/data_models.py,sha256=Suxa7xELdYuFNKqvGvFh8qyfVtAg79E-vaQ6dqNZOtA,3261
|
46
46
|
prediction_market_agent_tooling/markets/metaculus/metaculus.py,sha256=86TIx6cavEWc8Cv4KpZxSvwiSw9oFybXE3YB49pg-CA,4377
|
47
47
|
prediction_market_agent_tooling/markets/omen/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
48
|
-
prediction_market_agent_tooling/markets/omen/data_models.py,sha256=
|
49
|
-
prediction_market_agent_tooling/markets/omen/omen.py,sha256=
|
50
|
-
prediction_market_agent_tooling/markets/omen/omen_contracts.py,sha256=
|
48
|
+
prediction_market_agent_tooling/markets/omen/data_models.py,sha256=MBaWnUDGjYzbnDOHKPGrhAn0CP7iETVmsulRPqTf00I,28270
|
49
|
+
prediction_market_agent_tooling/markets/omen/omen.py,sha256=jrpfeMk8SUwk1p5QWCOm3Qt9HOHsux7DIBm77WRHqW4,51582
|
50
|
+
prediction_market_agent_tooling/markets/omen/omen_contracts.py,sha256=baXJwk-jSI3-FV-k239oCNOA4oKz6LT47juX8AKpW3A,28297
|
51
51
|
prediction_market_agent_tooling/markets/omen/omen_resolving.py,sha256=iDWdjICGkt968exwCjY-6nsnQyrrNAg3YjnDdP430GQ,9415
|
52
|
-
prediction_market_agent_tooling/markets/omen/omen_subgraph_handler.py,sha256=
|
52
|
+
prediction_market_agent_tooling/markets/omen/omen_subgraph_handler.py,sha256=IsnWiVSmaR5I82D49MpJpRu7uE-wkMEgubsLzt0qZVI,38125
|
53
53
|
prediction_market_agent_tooling/markets/polymarket/api.py,sha256=UZ4_TG8ceb9Y-qgsOKs8Qiv8zDt957QkT8IX2c83yqo,4800
|
54
54
|
prediction_market_agent_tooling/markets/polymarket/data_models.py,sha256=Fd5PI5y3mJM8VHExBhWFWEnuuIKxQmIAXgBuoPDvNjw,4341
|
55
55
|
prediction_market_agent_tooling/markets/polymarket/data_models_web.py,sha256=VZhVccTApygSKMmy6Au2G02JCJOKJnR_oVeKlaesuSg,12548
|
@@ -57,12 +57,12 @@ prediction_market_agent_tooling/markets/polymarket/polymarket.py,sha256=NRoZK71P
|
|
57
57
|
prediction_market_agent_tooling/markets/polymarket/utils.py,sha256=DImFxeMg8lTfsEDZ8FavndW38TfUsCkawcVGnucsuGo,2029
|
58
58
|
prediction_market_agent_tooling/markets/seer/data_models.py,sha256=2f6DOXhGerYbTSk5vUvw_y87TcUxOtSfca8-Et7imtU,643
|
59
59
|
prediction_market_agent_tooling/markets/seer/seer_subgraph_handler.py,sha256=Jola8AxmNDljBCzl6Gvjb9qH75Y7D5dAwbdZl_jndN8,5478
|
60
|
-
prediction_market_agent_tooling/monitor/financial_metrics/financial_metrics.py,sha256=
|
60
|
+
prediction_market_agent_tooling/monitor/financial_metrics/financial_metrics.py,sha256=fjIgjDIx5MhH5mwf7S0cspLOOSU3elYLhGYoIiM26mU,2746
|
61
61
|
prediction_market_agent_tooling/monitor/markets/manifold.py,sha256=TS4ERwTfQnot8dhekNyVNhJYf5ysYsjF-9v5_kM3aVI,3334
|
62
62
|
prediction_market_agent_tooling/monitor/markets/metaculus.py,sha256=LOnyWWBFdg10-cTWdb76nOsNjDloO8OfMT85GBzRCFI,1455
|
63
63
|
prediction_market_agent_tooling/monitor/markets/omen.py,sha256=EqiJYTvDbSu7fBpbrBmCuf3fc6GHr4MxWrBGa69MIyc,3305
|
64
64
|
prediction_market_agent_tooling/monitor/markets/polymarket.py,sha256=wak8o4BYaGbLpshQD12OrsqNABdanyID6ql95lEG2io,1870
|
65
|
-
prediction_market_agent_tooling/monitor/monitor.py,sha256
|
65
|
+
prediction_market_agent_tooling/monitor/monitor.py,sha256=4kMev1iGHQiEFslEqt5bWiXAyM_Qxb4rdMVKx2H9e1U,14235
|
66
66
|
prediction_market_agent_tooling/monitor/monitor_app.py,sha256=zNHSwH_KEiv8aOwvfo1JrNuSFMefpzXPWtellhnJpTI,4775
|
67
67
|
prediction_market_agent_tooling/monitor/monitor_settings.py,sha256=Xiozs3AsufuJ04JOe1vjUri-IAMWHjjmc2ugGGiHNH4,947
|
68
68
|
prediction_market_agent_tooling/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -72,37 +72,39 @@ prediction_market_agent_tooling/tools/betting_strategies/market_moving.py,sha256
|
|
72
72
|
prediction_market_agent_tooling/tools/betting_strategies/minimum_bet_to_win.py,sha256=-FUSuQQgjcWSSnoFxnlAyTeilY6raJABJVM2QKkFqAY,438
|
73
73
|
prediction_market_agent_tooling/tools/betting_strategies/stretch_bet_between.py,sha256=THMXwFlskvzbjnX_OiYtDSzI8XVFyULWfP2525_9UGc,429
|
74
74
|
prediction_market_agent_tooling/tools/betting_strategies/utils.py,sha256=kpIb-ci67Vc1Yqqaa-_S4OUkbhWSIYog4_Iwp69HU_k,97
|
75
|
-
prediction_market_agent_tooling/tools/caches/db_cache.py,sha256=
|
76
|
-
prediction_market_agent_tooling/tools/caches/inmemory_cache.py,sha256=
|
75
|
+
prediction_market_agent_tooling/tools/caches/db_cache.py,sha256=rkA7somZZo5G6OZVvNrCuCVc4kn7TUoPxmOq4J6BZ54,10391
|
76
|
+
prediction_market_agent_tooling/tools/caches/inmemory_cache.py,sha256=ZW5iI5rmjqeAebu5T7ftRnlkxiL02IC-MxCfDB80x7w,1506
|
77
|
+
prediction_market_agent_tooling/tools/caches/serializers.py,sha256=upSXN5__rmRlzJ6tv1h7FodKzJu9eCkFrN_zeuwroJM,2151
|
77
78
|
prediction_market_agent_tooling/tools/contract.py,sha256=Um_nQlpYJRBy4MnNR1CPKESehVwx_w35LwYX6T6py_0,20837
|
78
79
|
prediction_market_agent_tooling/tools/costs.py,sha256=EaAJ7v9laD4VEV3d8B44M4u3_oEO_H16jRVCdoZ93Uw,954
|
79
80
|
prediction_market_agent_tooling/tools/custom_exceptions.py,sha256=Fh8z1fbwONvP4-j7AmV_PuEcoqb6-QXa9PJ9m7guMcM,93
|
80
81
|
prediction_market_agent_tooling/tools/datetime_utc.py,sha256=2JSWF7AXQnv04_D_cu9Vmdkq0TWmGJ1QcK9AeqrA-U8,2765
|
82
|
+
prediction_market_agent_tooling/tools/db/db_manager.py,sha256=-WGYY-ZyqPveXb642gw4-Zh-RicMrBFgx7uqCB8TuDg,2801
|
81
83
|
prediction_market_agent_tooling/tools/google_utils.py,sha256=t3_UEEvKX3L0biSIQ560GdRbllQ6eprhK_upE243A-0,3185
|
82
84
|
prediction_market_agent_tooling/tools/hexbytes_custom.py,sha256=Bp94qgPjvjWf1Vb4lNzGFDXRdThw1rJ91vL6r2PWq5E,2096
|
83
|
-
prediction_market_agent_tooling/tools/httpx_cached_client.py,sha256=
|
85
|
+
prediction_market_agent_tooling/tools/httpx_cached_client.py,sha256=RxD-hwtZCMctnMwfzy8t51W9Z9gxFGtDYxBIMChazpc,406
|
84
86
|
prediction_market_agent_tooling/tools/image_gen/image_gen.py,sha256=HzRwBx62hOXBOmrtpkXaP9Qq1Ku03uUGdREocyjLQ_k,1266
|
85
87
|
prediction_market_agent_tooling/tools/image_gen/market_thumbnail_gen.py,sha256=jgOow4zw6g8dIJrog6Tp-3NQs4wjUJ3VgVKyMQv-0QM,1286
|
86
88
|
prediction_market_agent_tooling/tools/ipfs/ipfs_handler.py,sha256=CTTMfTvs_8PH4kAtlQby2aeEKwgpmxtuGbd4oYIdJ2A,1201
|
87
89
|
prediction_market_agent_tooling/tools/is_invalid.py,sha256=vuX0TKKhc_7iVnwAjXvfZeFwjr9nyYgREaYQDe-GYgA,5334
|
88
90
|
prediction_market_agent_tooling/tools/is_predictable.py,sha256=dSuL8eLnGNKd_MQ3CaT1OuQkAykr3m5kn7f8HHKgDcM,6797
|
89
91
|
prediction_market_agent_tooling/tools/langfuse_.py,sha256=jI_4ROxqo41CCnWGS1vN_AeDVhRzLMaQLxH3kxDu3L8,1153
|
90
|
-
prediction_market_agent_tooling/tools/langfuse_client_utils.py,sha256=
|
92
|
+
prediction_market_agent_tooling/tools/langfuse_client_utils.py,sha256=83T31s-YbsnNBLyYCjmBI2BBKUEqJUuYFa0uCdkoqy8,5901
|
91
93
|
prediction_market_agent_tooling/tools/omen/reality_accuracy.py,sha256=M1SF7iSW1gVlQSTskdVFTn09uPLST23YeipVIWj54io,2236
|
92
94
|
prediction_market_agent_tooling/tools/parallelism.py,sha256=6Gou0hbjtMZrYvxjTDFUDZuxmE2nqZVbb6hkg1hF82A,1022
|
93
95
|
prediction_market_agent_tooling/tools/relevant_news_analysis/data_models.py,sha256=95l84aztFaxcRLLcRQ46yKJbIlOEuDAbIGLouyliDzA,1316
|
94
96
|
prediction_market_agent_tooling/tools/relevant_news_analysis/relevant_news_analysis.py,sha256=CddJem7tk15NAudJDwmuL8znTycbR-YI8kTNtd3LzG8,5474
|
95
|
-
prediction_market_agent_tooling/tools/relevant_news_analysis/relevant_news_cache.py,sha256=
|
97
|
+
prediction_market_agent_tooling/tools/relevant_news_analysis/relevant_news_cache.py,sha256=ErLp284YlD7k_M8Si9OT86HuzfmSo1bPlLJtegXx1TA,3011
|
96
98
|
prediction_market_agent_tooling/tools/safe.py,sha256=9vxGGLvSPnfy-sxUFDpBTe8omqpGXP7MzvGPp6bRxrU,5197
|
97
99
|
prediction_market_agent_tooling/tools/singleton.py,sha256=CiIELUiI-OeS7U7eeHEt0rnVhtQGzwoUdAgn_7u_GBM,729
|
98
100
|
prediction_market_agent_tooling/tools/streamlit_user_login.py,sha256=NXEqfjT9Lc9QtliwSGRASIz1opjQ7Btme43H4qJbzgE,3010
|
99
101
|
prediction_market_agent_tooling/tools/tavily/tavily_models.py,sha256=5ldQs1pZe6uJ5eDAuP4OLpzmcqYShlIV67kttNFvGS0,342
|
100
102
|
prediction_market_agent_tooling/tools/tavily/tavily_search.py,sha256=Kw2mXNkMTYTEe1MBSTqhQmLoeXtgb6CkmHlcAJvhtqE,3809
|
101
|
-
prediction_market_agent_tooling/tools/transaction_cache.py,sha256=
|
103
|
+
prediction_market_agent_tooling/tools/transaction_cache.py,sha256=K5YKNL2_tR10Iw2TD9fuP-CTGpBbZtNdgbd0B_R7pjg,1814
|
102
104
|
prediction_market_agent_tooling/tools/utils.py,sha256=WvuUCHgMCiMq8_wMm5PHNwvLhcdDk2zGKaAM8OUC-qY,6438
|
103
105
|
prediction_market_agent_tooling/tools/web3_utils.py,sha256=hWDa7D-jP-iW647t0ATPyiUgKbAq25iH97KUnha25SQ,11944
|
104
|
-
prediction_market_agent_tooling-0.57.
|
105
|
-
prediction_market_agent_tooling-0.57.
|
106
|
-
prediction_market_agent_tooling-0.57.
|
107
|
-
prediction_market_agent_tooling-0.57.
|
108
|
-
prediction_market_agent_tooling-0.57.
|
106
|
+
prediction_market_agent_tooling-0.57.2.dist-info/LICENSE,sha256=6or154nLLU6bELzjh0mCreFjt0m2v72zLi3yHE0QbeE,7650
|
107
|
+
prediction_market_agent_tooling-0.57.2.dist-info/METADATA,sha256=tzVRrpZtV9Jty0w9XLwxGagZiC3scgqPP6d2cBhqp1A,8188
|
108
|
+
prediction_market_agent_tooling-0.57.2.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
|
109
|
+
prediction_market_agent_tooling-0.57.2.dist-info/entry_points.txt,sha256=m8PukHbeH5g0IAAmOf_1Ahm-sGAMdhSSRQmwtpmi2s8,81
|
110
|
+
prediction_market_agent_tooling-0.57.2.dist-info/RECORD,,
|
File without changes
|
File without changes
|