prediction-market-agent-tooling 0.69.5__py3-none-any.whl → 0.69.6__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/data_download/langfuse_data_downloader.py +1 -1
- prediction_market_agent_tooling/deploy/agent.py +1 -1
- prediction_market_agent_tooling/deploy/agent_example.py +1 -1
- prediction_market_agent_tooling/deploy/betting_strategy.py +1 -1
- prediction_market_agent_tooling/markets/market_type.py +74 -0
- prediction_market_agent_tooling/markets/markets.py +3 -68
- prediction_market_agent_tooling/markets/omen/omen.py +1 -1
- prediction_market_agent_tooling/markets/omen/omen_resolving.py +1 -1
- prediction_market_agent_tooling/markets/polymarket/polymarket.py +25 -3
- prediction_market_agent_tooling/markets/polymarket/polymarket_subgraph_handler.py +49 -8
- prediction_market_agent_tooling/markets/polymarket/utils.py +1 -1
- prediction_market_agent_tooling/tools/_generic_value.py +1 -1
- prediction_market_agent_tooling/tools/contract.py +29 -1
- prediction_market_agent_tooling/tools/contract_utils.py +61 -0
- prediction_market_agent_tooling/tools/openai_utils.py +31 -0
- prediction_market_agent_tooling/tools/streamlit_utils.py +188 -0
- {prediction_market_agent_tooling-0.69.5.dist-info → prediction_market_agent_tooling-0.69.6.dist-info}/METADATA +3 -2
- {prediction_market_agent_tooling-0.69.5.dist-info → prediction_market_agent_tooling-0.69.6.dist-info}/RECORD +21 -17
- {prediction_market_agent_tooling-0.69.5.dist-info → prediction_market_agent_tooling-0.69.6.dist-info}/LICENSE +0 -0
- {prediction_market_agent_tooling-0.69.5.dist-info → prediction_market_agent_tooling-0.69.6.dist-info}/WHEEL +0 -0
- {prediction_market_agent_tooling-0.69.5.dist-info → prediction_market_agent_tooling-0.69.6.dist-info}/entry_points.txt +0 -0
@@ -16,7 +16,7 @@ from prediction_market_agent_tooling.gtypes import DatetimeUTC, OutcomeStr, Outc
|
|
16
16
|
from prediction_market_agent_tooling.loggers import logger
|
17
17
|
from prediction_market_agent_tooling.markets.agent_market import AgentMarket
|
18
18
|
from prediction_market_agent_tooling.markets.data_models import Resolution
|
19
|
-
from prediction_market_agent_tooling.markets.
|
19
|
+
from prediction_market_agent_tooling.markets.market_type import MarketType
|
20
20
|
from prediction_market_agent_tooling.markets.omen.omen import OmenAgentMarket
|
21
21
|
from prediction_market_agent_tooling.markets.seer.seer import SeerAgentMarket
|
22
22
|
from prediction_market_agent_tooling.markets.seer.seer_subgraph_handler import (
|
@@ -36,7 +36,7 @@ from prediction_market_agent_tooling.markets.data_models import (
|
|
36
36
|
ScalarProbabilisticAnswer,
|
37
37
|
Trade,
|
38
38
|
)
|
39
|
-
from prediction_market_agent_tooling.markets.
|
39
|
+
from prediction_market_agent_tooling.markets.market_type import MarketType
|
40
40
|
from prediction_market_agent_tooling.tools.custom_exceptions import (
|
41
41
|
CantPayForGasError,
|
42
42
|
OutOfFundsError,
|
@@ -6,7 +6,7 @@ from prediction_market_agent_tooling.markets.agent_market import AgentMarket, So
|
|
6
6
|
from prediction_market_agent_tooling.markets.data_models import (
|
7
7
|
CategoricalProbabilisticAnswer,
|
8
8
|
)
|
9
|
-
from prediction_market_agent_tooling.markets.
|
9
|
+
from prediction_market_agent_tooling.markets.market_type import MarketType
|
10
10
|
|
11
11
|
|
12
12
|
class DeployableCoinFlipAgent(DeployableTraderAgent):
|
@@ -26,7 +26,7 @@ from prediction_market_agent_tooling.markets.data_models import (
|
|
26
26
|
Trade,
|
27
27
|
TradeType,
|
28
28
|
)
|
29
|
-
from prediction_market_agent_tooling.markets.
|
29
|
+
from prediction_market_agent_tooling.markets.market_type import MarketType
|
30
30
|
from prediction_market_agent_tooling.markets.omen.omen import (
|
31
31
|
get_buy_outcome_token_amount,
|
32
32
|
)
|
@@ -0,0 +1,74 @@
|
|
1
|
+
from enum import Enum
|
2
|
+
from typing import TypeVar
|
3
|
+
|
4
|
+
from prediction_market_agent_tooling.jobs.jobs_models import JobAgentMarket
|
5
|
+
from prediction_market_agent_tooling.jobs.omen.omen_jobs import OmenJobAgentMarket
|
6
|
+
from prediction_market_agent_tooling.markets.agent_market import AgentMarket
|
7
|
+
from prediction_market_agent_tooling.markets.manifold.manifold import (
|
8
|
+
ManifoldAgentMarket,
|
9
|
+
)
|
10
|
+
from prediction_market_agent_tooling.markets.metaculus.metaculus import (
|
11
|
+
MetaculusAgentMarket,
|
12
|
+
)
|
13
|
+
from prediction_market_agent_tooling.markets.omen.omen import OmenAgentMarket
|
14
|
+
from prediction_market_agent_tooling.markets.polymarket.polymarket import (
|
15
|
+
PolymarketAgentMarket,
|
16
|
+
)
|
17
|
+
from prediction_market_agent_tooling.markets.seer.seer import SeerAgentMarket
|
18
|
+
|
19
|
+
T = TypeVar("T", bound=AgentMarket)
|
20
|
+
|
21
|
+
|
22
|
+
class MarketType(str, Enum):
|
23
|
+
# Note: Always keep the omen market first, as it is the main market for us.
|
24
|
+
OMEN = "omen"
|
25
|
+
MANIFOLD = "manifold"
|
26
|
+
POLYMARKET = "polymarket"
|
27
|
+
METACULUS = "metaculus"
|
28
|
+
SEER = "seer"
|
29
|
+
|
30
|
+
@staticmethod
|
31
|
+
def from_market(market: AgentMarket) -> "MarketType":
|
32
|
+
return AGENT_MARKET_TO_MARKET_TYPE[type(market)]
|
33
|
+
|
34
|
+
@property
|
35
|
+
def market_class(self) -> type[AgentMarket]:
|
36
|
+
if self not in MARKET_TYPE_TO_AGENT_MARKET:
|
37
|
+
raise ValueError(f"Unknown market type: {self}")
|
38
|
+
return MARKET_TYPE_TO_AGENT_MARKET[self]
|
39
|
+
|
40
|
+
@property
|
41
|
+
def job_class(self) -> type[JobAgentMarket]:
|
42
|
+
if self not in JOB_MARKET_TYPE_TO_JOB_AGENT_MARKET:
|
43
|
+
raise ValueError(f"Unknown market type: {self}")
|
44
|
+
return JOB_MARKET_TYPE_TO_JOB_AGENT_MARKET[self]
|
45
|
+
|
46
|
+
@property
|
47
|
+
def is_trading_market(self) -> bool:
|
48
|
+
return self in [
|
49
|
+
MarketType.OMEN,
|
50
|
+
MarketType.POLYMARKET,
|
51
|
+
MarketType.SEER,
|
52
|
+
MarketType.MANIFOLD,
|
53
|
+
]
|
54
|
+
|
55
|
+
@property
|
56
|
+
def is_blockchain_market(self) -> bool:
|
57
|
+
return self in [MarketType.OMEN, MarketType.POLYMARKET, MarketType.SEER]
|
58
|
+
|
59
|
+
|
60
|
+
MARKET_TYPE_TO_AGENT_MARKET: dict[MarketType, type[AgentMarket]] = {
|
61
|
+
MarketType.MANIFOLD: ManifoldAgentMarket,
|
62
|
+
MarketType.OMEN: OmenAgentMarket,
|
63
|
+
MarketType.POLYMARKET: PolymarketAgentMarket,
|
64
|
+
MarketType.METACULUS: MetaculusAgentMarket,
|
65
|
+
MarketType.SEER: SeerAgentMarket,
|
66
|
+
}
|
67
|
+
|
68
|
+
AGENT_MARKET_TO_MARKET_TYPE: dict[type[AgentMarket], MarketType] = {
|
69
|
+
v: k for k, v in MARKET_TYPE_TO_AGENT_MARKET.items()
|
70
|
+
}
|
71
|
+
|
72
|
+
JOB_MARKET_TYPE_TO_JOB_AGENT_MARKET: dict[MarketType, type[JobAgentMarket]] = {
|
73
|
+
MarketType.OMEN: OmenJobAgentMarket,
|
74
|
+
}
|
@@ -1,83 +1,18 @@
|
|
1
1
|
import typing as t
|
2
|
-
from enum import Enum
|
3
2
|
|
4
|
-
from prediction_market_agent_tooling.jobs.jobs_models import JobAgentMarket
|
5
|
-
from prediction_market_agent_tooling.jobs.omen.omen_jobs import OmenJobAgentMarket
|
6
3
|
from prediction_market_agent_tooling.markets.agent_market import (
|
7
4
|
AgentMarket,
|
8
5
|
FilterBy,
|
9
6
|
QuestionType,
|
10
7
|
SortBy,
|
11
8
|
)
|
12
|
-
from prediction_market_agent_tooling.markets.
|
13
|
-
|
9
|
+
from prediction_market_agent_tooling.markets.market_type import (
|
10
|
+
MARKET_TYPE_TO_AGENT_MARKET,
|
11
|
+
MarketType,
|
14
12
|
)
|
15
|
-
from prediction_market_agent_tooling.markets.metaculus.metaculus import (
|
16
|
-
MetaculusAgentMarket,
|
17
|
-
)
|
18
|
-
from prediction_market_agent_tooling.markets.omen.omen import OmenAgentMarket
|
19
|
-
from prediction_market_agent_tooling.markets.polymarket.polymarket import (
|
20
|
-
PolymarketAgentMarket,
|
21
|
-
)
|
22
|
-
from prediction_market_agent_tooling.markets.seer.seer import SeerAgentMarket
|
23
13
|
from prediction_market_agent_tooling.tools.utils import DatetimeUTC
|
24
14
|
|
25
15
|
|
26
|
-
class MarketType(str, Enum):
|
27
|
-
# Note: Always keep the omen market first, as it is the main market for us.
|
28
|
-
OMEN = "omen"
|
29
|
-
MANIFOLD = "manifold"
|
30
|
-
POLYMARKET = "polymarket"
|
31
|
-
METACULUS = "metaculus"
|
32
|
-
SEER = "seer"
|
33
|
-
|
34
|
-
@staticmethod
|
35
|
-
def from_market(market: AgentMarket) -> "MarketType":
|
36
|
-
return AGENT_MARKET_TO_MARKET_TYPE[type(market)]
|
37
|
-
|
38
|
-
@property
|
39
|
-
def market_class(self) -> type[AgentMarket]:
|
40
|
-
if self not in MARKET_TYPE_TO_AGENT_MARKET:
|
41
|
-
raise ValueError(f"Unknown market type: {self}")
|
42
|
-
return MARKET_TYPE_TO_AGENT_MARKET[self]
|
43
|
-
|
44
|
-
@property
|
45
|
-
def job_class(self) -> type[JobAgentMarket]:
|
46
|
-
if self not in JOB_MARKET_TYPE_TO_JOB_AGENT_MARKET:
|
47
|
-
raise ValueError(f"Unknown market type: {self}")
|
48
|
-
return JOB_MARKET_TYPE_TO_JOB_AGENT_MARKET[self]
|
49
|
-
|
50
|
-
@property
|
51
|
-
def is_trading_market(self) -> bool:
|
52
|
-
return self in [
|
53
|
-
MarketType.OMEN,
|
54
|
-
MarketType.POLYMARKET,
|
55
|
-
MarketType.SEER,
|
56
|
-
MarketType.MANIFOLD,
|
57
|
-
]
|
58
|
-
|
59
|
-
@property
|
60
|
-
def is_blockchain_market(self) -> bool:
|
61
|
-
return self in [MarketType.OMEN, MarketType.POLYMARKET, MarketType.SEER]
|
62
|
-
|
63
|
-
|
64
|
-
MARKET_TYPE_TO_AGENT_MARKET: dict[MarketType, type[AgentMarket]] = {
|
65
|
-
MarketType.MANIFOLD: ManifoldAgentMarket,
|
66
|
-
MarketType.OMEN: OmenAgentMarket,
|
67
|
-
MarketType.POLYMARKET: PolymarketAgentMarket,
|
68
|
-
MarketType.METACULUS: MetaculusAgentMarket,
|
69
|
-
MarketType.SEER: SeerAgentMarket,
|
70
|
-
}
|
71
|
-
|
72
|
-
AGENT_MARKET_TO_MARKET_TYPE: dict[type[AgentMarket], MarketType] = {
|
73
|
-
v: k for k, v in MARKET_TYPE_TO_AGENT_MARKET.items()
|
74
|
-
}
|
75
|
-
|
76
|
-
JOB_MARKET_TYPE_TO_JOB_AGENT_MARKET: dict[MarketType, type[JobAgentMarket]] = {
|
77
|
-
MarketType.OMEN: OmenJobAgentMarket,
|
78
|
-
}
|
79
|
-
|
80
|
-
|
81
16
|
def get_binary_markets(
|
82
17
|
limit: int,
|
83
18
|
market_type: MarketType,
|
@@ -1114,7 +1114,7 @@ def get_conditional_tokens_balance_for_market(
|
|
1114
1114
|
|
1115
1115
|
for index_set in market.condition.index_sets:
|
1116
1116
|
collection_id = conditional_token_contract.getCollectionId(
|
1117
|
-
parent_collection_id, market.condition.id, index_set, web3=web3
|
1117
|
+
HexBytes(parent_collection_id), market.condition.id, index_set, web3=web3
|
1118
1118
|
)
|
1119
1119
|
# Note that collection_id is returned as bytes, which is accepted by the contract calls downstream.
|
1120
1120
|
position_id: int = conditional_token_contract.getPositionId(
|
@@ -13,7 +13,7 @@ from prediction_market_agent_tooling.markets.data_models import Resolution
|
|
13
13
|
from prediction_market_agent_tooling.markets.manifold.api import (
|
14
14
|
find_resolution_on_manifold,
|
15
15
|
)
|
16
|
-
from prediction_market_agent_tooling.markets.
|
16
|
+
from prediction_market_agent_tooling.markets.market_type import MarketType
|
17
17
|
from prediction_market_agent_tooling.markets.omen.data_models import (
|
18
18
|
OmenMarket,
|
19
19
|
RealityQuestion,
|
@@ -46,6 +46,7 @@ from prediction_market_agent_tooling.markets.polymarket.data_models import (
|
|
46
46
|
PolymarketGammaResponseDataItem,
|
47
47
|
)
|
48
48
|
from prediction_market_agent_tooling.markets.polymarket.polymarket_contracts import (
|
49
|
+
PolymarketConditionalTokenContract,
|
49
50
|
USDCeContract,
|
50
51
|
)
|
51
52
|
from prediction_market_agent_tooling.markets.polymarket.polymarket_subgraph_handler import (
|
@@ -266,9 +267,30 @@ class PolymarketAgentMarket(AgentMarket):
|
|
266
267
|
)
|
267
268
|
|
268
269
|
@staticmethod
|
269
|
-
def redeem_winnings(api_keys: APIKeys) -> None:
|
270
|
-
|
271
|
-
|
270
|
+
def redeem_winnings(api_keys: APIKeys, web3: Web3 | None = None) -> None:
|
271
|
+
web3 = web3 or RPCConfig().get_polygon_web3()
|
272
|
+
user_id = api_keys.bet_from_address
|
273
|
+
conditional_token_contract = PolymarketConditionalTokenContract()
|
274
|
+
positions = PolymarketSubgraphHandler().get_market_positions_from_user(user_id)
|
275
|
+
for pos in positions:
|
276
|
+
if (
|
277
|
+
pos.market.condition.resolutionTimestamp is None
|
278
|
+
or pos.market.condition.payoutNumerators is None
|
279
|
+
):
|
280
|
+
continue
|
281
|
+
|
282
|
+
condition_id = pos.market.condition.id
|
283
|
+
index_sets = pos.market.condition.index_sets
|
284
|
+
|
285
|
+
redeem_event = conditional_token_contract.redeemPositions(
|
286
|
+
api_keys=api_keys,
|
287
|
+
collateral_token_address=USDCeContract().address,
|
288
|
+
condition_id=condition_id,
|
289
|
+
index_sets=index_sets,
|
290
|
+
web3=web3,
|
291
|
+
)
|
292
|
+
|
293
|
+
logger.info(f"Redeemed {redeem_event=} from condition_id {condition_id=}.")
|
272
294
|
|
273
295
|
@staticmethod
|
274
296
|
def verify_operational_balance(api_keys: APIKeys) -> bool:
|
@@ -1,6 +1,7 @@
|
|
1
1
|
from pydantic import BaseModel
|
2
|
+
from subgrounds import FieldPath
|
2
3
|
|
3
|
-
from prediction_market_agent_tooling.gtypes import HexBytes
|
4
|
+
from prediction_market_agent_tooling.gtypes import ChecksumAddress, HexBytes
|
4
5
|
from prediction_market_agent_tooling.markets.base_subgraph_handler import (
|
5
6
|
BaseSubgraphHandler,
|
6
7
|
)
|
@@ -12,6 +13,20 @@ class ConditionSubgraphModel(BaseModel):
|
|
12
13
|
payoutNumerators: list[int] | None = None
|
13
14
|
outcomeSlotCount: int
|
14
15
|
resolutionTimestamp: int | None = None
|
16
|
+
questionId: HexBytes
|
17
|
+
|
18
|
+
@property
|
19
|
+
def index_sets(self) -> list[int]:
|
20
|
+
return [i + 1 for i in range(self.outcomeSlotCount)]
|
21
|
+
|
22
|
+
|
23
|
+
class MarketPositionMarket(BaseModel):
|
24
|
+
condition: ConditionSubgraphModel
|
25
|
+
|
26
|
+
|
27
|
+
class MarketPosition(BaseModel):
|
28
|
+
id: HexBytes
|
29
|
+
market: MarketPositionMarket
|
15
30
|
|
16
31
|
|
17
32
|
class PolymarketSubgraphHandler(BaseSubgraphHandler):
|
@@ -27,6 +42,16 @@ class PolymarketSubgraphHandler(BaseSubgraphHandler):
|
|
27
42
|
)
|
28
43
|
)
|
29
44
|
|
45
|
+
def _get_fields_for_condition(self, field: FieldPath) -> list[FieldPath]:
|
46
|
+
return [
|
47
|
+
field.id,
|
48
|
+
field.questionId,
|
49
|
+
field.payoutNumerators,
|
50
|
+
field.payoutDenominator,
|
51
|
+
field.outcomeSlotCount,
|
52
|
+
field.resolutionTimestamp,
|
53
|
+
]
|
54
|
+
|
30
55
|
def get_conditions(
|
31
56
|
self, condition_ids: list[HexBytes]
|
32
57
|
) -> list[ConditionSubgraphModel]:
|
@@ -36,15 +61,31 @@ class PolymarketSubgraphHandler(BaseSubgraphHandler):
|
|
36
61
|
where=where_stms,
|
37
62
|
)
|
38
63
|
|
39
|
-
condition_fields =
|
40
|
-
conditions.id,
|
41
|
-
conditions.payoutNumerators,
|
42
|
-
conditions.payoutDenominator,
|
43
|
-
conditions.outcomeSlotCount,
|
44
|
-
conditions.resolutionTimestamp,
|
45
|
-
]
|
64
|
+
condition_fields = self._get_fields_for_condition(conditions)
|
46
65
|
|
47
66
|
conditions_models = self.do_query(
|
48
67
|
fields=condition_fields, pydantic_model=ConditionSubgraphModel
|
49
68
|
)
|
50
69
|
return conditions_models
|
70
|
+
|
71
|
+
def get_market_positions_from_user(
|
72
|
+
self,
|
73
|
+
user: ChecksumAddress,
|
74
|
+
first: int = 1000,
|
75
|
+
block_number: int | None = None,
|
76
|
+
) -> list[MarketPosition]:
|
77
|
+
# Not possible to filter using `market_.condition` on a subgraph level, bad indexers error.
|
78
|
+
positions = self.conditions_subgraph.Query.marketPositions(
|
79
|
+
first=first,
|
80
|
+
where={"user": user.lower()},
|
81
|
+
block={"number": block_number} if block_number else None,
|
82
|
+
)
|
83
|
+
|
84
|
+
condition_fields = self._get_fields_for_condition(
|
85
|
+
positions.market.condition
|
86
|
+
) + [positions.id]
|
87
|
+
|
88
|
+
positions_models = self.do_query(
|
89
|
+
fields=condition_fields, pydantic_model=MarketPosition
|
90
|
+
)
|
91
|
+
return positions_models
|
@@ -239,7 +239,7 @@ class _GenericValue(
|
|
239
239
|
cls, source_type: t.Any, handler: GetCoreSchemaHandler
|
240
240
|
) -> CoreSchema:
|
241
241
|
# Support for Pydantic usage.
|
242
|
-
dt_schema = handler(
|
242
|
+
dt_schema = handler(cls.parser | str | dict)
|
243
243
|
return core_schema.no_info_after_validator_function(
|
244
244
|
lambda x: cls(x["value"] if isinstance(x, dict) else x),
|
245
245
|
dt_schema,
|
@@ -665,7 +665,7 @@ class ConditionalTokenContract(ContractBaseClass):
|
|
665
665
|
|
666
666
|
def getCollectionId(
|
667
667
|
self,
|
668
|
-
parent_collection_id:
|
668
|
+
parent_collection_id: HexBytes,
|
669
669
|
condition_id: HexBytes,
|
670
670
|
index_set: int,
|
671
671
|
web3: Web3 | None = None,
|
@@ -773,6 +773,34 @@ class ConditionalTokenContract(ContractBaseClass):
|
|
773
773
|
)
|
774
774
|
return payoutForCondition
|
775
775
|
|
776
|
+
def splitPosition(
|
777
|
+
self,
|
778
|
+
api_keys: APIKeys,
|
779
|
+
collateral_token: ChecksumAddress,
|
780
|
+
condition_id: HexBytes,
|
781
|
+
outcome_slot_count: int,
|
782
|
+
amount_wei: Wei,
|
783
|
+
parent_collateral_id: HexBytes = HexBytes(HASH_ZERO),
|
784
|
+
tx_params: t.Optional[TxParams] = None,
|
785
|
+
web3: Web3 | None = None,
|
786
|
+
) -> TxReceipt:
|
787
|
+
# We always split the full set of outcome tokens (for simplicity)
|
788
|
+
# partitions are given in bitmasks, i.e. outcomes are 1,2,4,8,etc.
|
789
|
+
partition = [2**i for i in range(outcome_slot_count)]
|
790
|
+
return self.send(
|
791
|
+
api_keys=api_keys,
|
792
|
+
function_name="splitPosition",
|
793
|
+
function_params=[
|
794
|
+
collateral_token,
|
795
|
+
parent_collateral_id,
|
796
|
+
condition_id,
|
797
|
+
partition,
|
798
|
+
amount_wei,
|
799
|
+
],
|
800
|
+
tx_params=tx_params,
|
801
|
+
web3=web3,
|
802
|
+
)
|
803
|
+
|
776
804
|
def setApprovalForAll(
|
777
805
|
self,
|
778
806
|
api_keys: APIKeys,
|
@@ -0,0 +1,61 @@
|
|
1
|
+
from web3 import Web3
|
2
|
+
|
3
|
+
from prediction_market_agent_tooling.config import RPCConfig
|
4
|
+
from prediction_market_agent_tooling.gtypes import ChecksumAddress
|
5
|
+
from prediction_market_agent_tooling.tools.contract import contract_implements_function
|
6
|
+
|
7
|
+
|
8
|
+
def is_erc20_contract(address: ChecksumAddress, web3: Web3 | None = None) -> bool:
|
9
|
+
"""
|
10
|
+
Checks if the given address is an ERC20-compatible contract.
|
11
|
+
|
12
|
+
It estimates it by looking if it implements symbol, name, decimals, totalSupply, balanceOf.
|
13
|
+
"""
|
14
|
+
web3 = web3 or RPCConfig().get_web3()
|
15
|
+
return (
|
16
|
+
contract_implements_function(address, "symbol", web3)
|
17
|
+
and contract_implements_function(address, "name", web3)
|
18
|
+
and contract_implements_function(address, "totalSupply", web3)
|
19
|
+
and contract_implements_function(
|
20
|
+
address, "balanceOf", web3, function_arg_types=["address"]
|
21
|
+
)
|
22
|
+
)
|
23
|
+
|
24
|
+
|
25
|
+
def is_nft_contract(address: ChecksumAddress, web3: Web3 | None = None) -> bool:
|
26
|
+
"""
|
27
|
+
Checks if the given address is an NFT-compatible contract (ERC721 or ERC1155).
|
28
|
+
|
29
|
+
For ERC721, checks for: ownerOf, balanceOf, transferFrom.
|
30
|
+
For ERC1155, checks for: balanceOf, safeTransferFrom.
|
31
|
+
|
32
|
+
Returns True if either ERC721 or ERC1155 interface is detected.
|
33
|
+
"""
|
34
|
+
web3 = web3 or RPCConfig().get_web3()
|
35
|
+
is_erc721 = (
|
36
|
+
contract_implements_function(
|
37
|
+
address, "ownerOf", web3, function_arg_types=["uint256"]
|
38
|
+
)
|
39
|
+
and contract_implements_function(
|
40
|
+
address, "balanceOf", web3, function_arg_types=["address"]
|
41
|
+
)
|
42
|
+
and contract_implements_function(
|
43
|
+
address,
|
44
|
+
"transferFrom",
|
45
|
+
web3,
|
46
|
+
function_arg_types=["address", "address", "uint256"],
|
47
|
+
)
|
48
|
+
)
|
49
|
+
if is_erc721:
|
50
|
+
return True
|
51
|
+
is_erc1155 = contract_implements_function(
|
52
|
+
address, "balanceOf", web3, function_arg_types=["address", "uint256"]
|
53
|
+
) and contract_implements_function(
|
54
|
+
address,
|
55
|
+
"safeTransferFrom",
|
56
|
+
web3,
|
57
|
+
function_arg_types=["address", "address", "uint256", "uint256", "bytes"],
|
58
|
+
)
|
59
|
+
if is_erc1155:
|
60
|
+
return True
|
61
|
+
return False
|
@@ -0,0 +1,31 @@
|
|
1
|
+
from langfuse.openai import AsyncOpenAI
|
2
|
+
from openai import DEFAULT_TIMEOUT, DefaultAsyncHttpxClient
|
3
|
+
from pydantic import SecretStr
|
4
|
+
from pydantic_ai.models.openai import OpenAIModel # noqa: F401 # Just for convenience.
|
5
|
+
from pydantic_ai.providers.openai import OpenAIProvider
|
6
|
+
|
7
|
+
OPENAI_BASE_URL = "https://api.openai.com/v1"
|
8
|
+
|
9
|
+
|
10
|
+
def get_openai_provider(
|
11
|
+
api_key: SecretStr,
|
12
|
+
base_url: str = OPENAI_BASE_URL,
|
13
|
+
) -> OpenAIProvider:
|
14
|
+
"""
|
15
|
+
For some reason, when OpenAIProvider/AsyncOpenAI is initialised without the http_client directly provided, and it's used with Langfuse observer decorator,
|
16
|
+
we are getting false error messages.
|
17
|
+
|
18
|
+
Unfortunatelly, Langfuse doesn't seem eager to fix this, so this is a workaround. See https://github.com/langfuse/langfuse/issues/5622.
|
19
|
+
|
20
|
+
Use this function as a helper function to create bug-free OpenAIProvider.
|
21
|
+
"""
|
22
|
+
return OpenAIProvider(
|
23
|
+
openai_client=AsyncOpenAI(
|
24
|
+
api_key=api_key.get_secret_value(),
|
25
|
+
base_url=base_url,
|
26
|
+
http_client=DefaultAsyncHttpxClient(
|
27
|
+
timeout=DEFAULT_TIMEOUT,
|
28
|
+
base_url=base_url,
|
29
|
+
),
|
30
|
+
)
|
31
|
+
)
|
@@ -0,0 +1,188 @@
|
|
1
|
+
import asyncio
|
2
|
+
import os
|
3
|
+
import typing as t
|
4
|
+
|
5
|
+
import streamlit
|
6
|
+
import streamlit as st
|
7
|
+
|
8
|
+
from prediction_market_agent_tooling.config import APIKeys
|
9
|
+
from prediction_market_agent_tooling.loggers import logger
|
10
|
+
from prediction_market_agent_tooling.tools.caches.db_cache import DB_CACHE_LOG_PREFIX
|
11
|
+
|
12
|
+
if t.TYPE_CHECKING:
|
13
|
+
from loguru import Message
|
14
|
+
|
15
|
+
STREAMLIT_SINK_EXPLICIT_FLAG = "streamlit"
|
16
|
+
|
17
|
+
|
18
|
+
def streamlit_asyncio_event_loop_hack() -> None:
|
19
|
+
"""
|
20
|
+
This function is a hack to make Streamlit work with asyncio event loop.
|
21
|
+
See https://github.com/streamlit/streamlit/issues/744
|
22
|
+
"""
|
23
|
+
|
24
|
+
def get_or_create_eventloop() -> asyncio.AbstractEventLoop:
|
25
|
+
try:
|
26
|
+
return asyncio.get_event_loop()
|
27
|
+
except RuntimeError as ex:
|
28
|
+
if "There is no current event loop in thread" in str(ex):
|
29
|
+
loop = asyncio.new_event_loop()
|
30
|
+
asyncio.set_event_loop(loop)
|
31
|
+
return asyncio.get_event_loop()
|
32
|
+
else:
|
33
|
+
raise ex
|
34
|
+
|
35
|
+
loop = get_or_create_eventloop()
|
36
|
+
asyncio.set_event_loop(loop)
|
37
|
+
|
38
|
+
|
39
|
+
def check_required_api_keys(keys: APIKeys, required_keys: list[str]) -> None:
|
40
|
+
has_missing_keys = False
|
41
|
+
for key in required_keys:
|
42
|
+
if not getattr(keys, key):
|
43
|
+
st.error(f"Environment variable for key {key} has not been set.")
|
44
|
+
has_missing_keys = True
|
45
|
+
if has_missing_keys:
|
46
|
+
st.stop()
|
47
|
+
|
48
|
+
|
49
|
+
def get_loguru_streamlit_sink(
|
50
|
+
explicit: bool,
|
51
|
+
expander_if_longer_than: int | None,
|
52
|
+
include_in_expander: int = 50,
|
53
|
+
) -> t.Callable[["Message"], None]:
|
54
|
+
def loguru_streamlit_sink(log: "Message") -> None:
|
55
|
+
record = log.record
|
56
|
+
level = record["level"].name
|
57
|
+
|
58
|
+
message = streamlit_escape(record["message"])
|
59
|
+
|
60
|
+
# Ignore certain messages that aren't interesting for Streamlit user, but are in the production logs.
|
61
|
+
if any(x in message for x in [DB_CACHE_LOG_PREFIX]):
|
62
|
+
return
|
63
|
+
|
64
|
+
if explicit and not record["extra"].get(STREAMLIT_SINK_EXPLICIT_FLAG, False):
|
65
|
+
return
|
66
|
+
|
67
|
+
if level == "ERROR":
|
68
|
+
st_func = st.error
|
69
|
+
st_icon = "❌"
|
70
|
+
|
71
|
+
elif level == "WARNING":
|
72
|
+
st_func = st.warning
|
73
|
+
st_icon = "⚠️"
|
74
|
+
|
75
|
+
elif level == "SUCCESS":
|
76
|
+
st_func = st.success
|
77
|
+
st_icon = "✅"
|
78
|
+
|
79
|
+
elif level == "DEBUG":
|
80
|
+
st_func = None
|
81
|
+
st_icon = None
|
82
|
+
|
83
|
+
else:
|
84
|
+
st_func = st.info
|
85
|
+
st_icon = "ℹ️"
|
86
|
+
|
87
|
+
if st_func is None:
|
88
|
+
pass
|
89
|
+
|
90
|
+
elif (
|
91
|
+
expander_if_longer_than is not None
|
92
|
+
and len(message) > expander_if_longer_than
|
93
|
+
):
|
94
|
+
with st.expander(
|
95
|
+
f"[Expand to see more] {message[:include_in_expander]}..."
|
96
|
+
):
|
97
|
+
st_func(message, icon=st_icon)
|
98
|
+
|
99
|
+
else:
|
100
|
+
st_func(message, icon=st_icon)
|
101
|
+
|
102
|
+
return loguru_streamlit_sink
|
103
|
+
|
104
|
+
|
105
|
+
@st.cache_resource
|
106
|
+
def add_sink_to_logger(
|
107
|
+
explicit: bool = False, expander_if_longer_than: int | None = 500
|
108
|
+
) -> None:
|
109
|
+
"""
|
110
|
+
Adds streamlit as a sink to the loguru, so any loguru logs will be shown in the streamlit app.
|
111
|
+
|
112
|
+
Needs to be behind a cache decorator, so it only runs once per streamlit session (otherwise we would see duplicated messages).
|
113
|
+
|
114
|
+
If `explicit` is set to True, only logged messages with extra attribute `streamlit` will be shown in the streamlit app.
|
115
|
+
"""
|
116
|
+
logger.add(
|
117
|
+
get_loguru_streamlit_sink(
|
118
|
+
explicit=explicit, expander_if_longer_than=expander_if_longer_than
|
119
|
+
)
|
120
|
+
)
|
121
|
+
|
122
|
+
|
123
|
+
def streamlit_escape(message: str) -> str:
|
124
|
+
"""
|
125
|
+
Escapes the string for streamlit writes.
|
126
|
+
"""
|
127
|
+
# Replace escaped newlines with actual newlines.
|
128
|
+
message = message.replace("\\n", "\n")
|
129
|
+
# Fix malformed dollar signs in the messages.
|
130
|
+
message = message.replace("$", "\$")
|
131
|
+
|
132
|
+
return message
|
133
|
+
|
134
|
+
|
135
|
+
def dict_to_point_list(d: dict[str, t.Any], indent: int = 0) -> str:
|
136
|
+
"""
|
137
|
+
Helper method to convert nested dicts to a bullet point list.
|
138
|
+
"""
|
139
|
+
lines = []
|
140
|
+
prefix = " " * indent
|
141
|
+
for k, v in d.items():
|
142
|
+
if isinstance(v, dict):
|
143
|
+
lines.append(f"{prefix}- {k}:")
|
144
|
+
lines.append(dict_to_point_list(v, indent + 1))
|
145
|
+
elif isinstance(v, list):
|
146
|
+
lines.append(f"{prefix}- {k}:")
|
147
|
+
for idx, item in enumerate(v):
|
148
|
+
if isinstance(item, dict):
|
149
|
+
lines.append(f"{prefix} - item {idx}:")
|
150
|
+
lines.append(dict_to_point_list(item, indent + 2))
|
151
|
+
else:
|
152
|
+
lines.append(f"{prefix} - item {idx}: {item}")
|
153
|
+
else:
|
154
|
+
lines.append(f"{prefix}- {k}: {v}")
|
155
|
+
return "\n".join(lines)
|
156
|
+
|
157
|
+
|
158
|
+
def customize_index_html(head_content: str) -> None:
|
159
|
+
"""
|
160
|
+
Unfortunatelly, Streamlit doesn't allow to update HTML content of the main index.html file, any component that allows passing of HTML will render it in iframe.
|
161
|
+
That's unusable for analytics tools like Posthog.
|
162
|
+
|
163
|
+
This is workaround that patches their index.html file directly in their package, found in https://stackoverflow.com/questions/70520191/how-to-add-the-google-analytics-tag-to-website-developed-with-streamlit/78992559#78992559.
|
164
|
+
|
165
|
+
There is also an issue that tracks this feature (open since 2023): https://github.com/streamlit/streamlit/issues/6140
|
166
|
+
"""
|
167
|
+
streamlit_package_dir = os.path.dirname(streamlit.__file__)
|
168
|
+
index_path = os.path.join(streamlit_package_dir, "static", "index.html")
|
169
|
+
|
170
|
+
with open(index_path, "r") as f:
|
171
|
+
index_html = f.read()
|
172
|
+
|
173
|
+
if head_content not in index_html:
|
174
|
+
# Add the custom content to the head
|
175
|
+
index_html = index_html.replace("</head>", f"{head_content}</head>")
|
176
|
+
|
177
|
+
# Replace the <title> tag
|
178
|
+
index_html = index_html.replace(
|
179
|
+
"<title>Streamlit</title>", "<title>Savantly is cool</title>"
|
180
|
+
)
|
181
|
+
|
182
|
+
with open(index_path, "w") as f:
|
183
|
+
f.write(index_html)
|
184
|
+
|
185
|
+
logger.info("index.html injected with custom code.")
|
186
|
+
|
187
|
+
else:
|
188
|
+
logger.info("index.html injection skipped because it's already present.")
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: prediction-market-agent-tooling
|
3
|
-
Version: 0.69.
|
3
|
+
Version: 0.69.6
|
4
4
|
Summary: Tools to benchmark, deploy and monitor prediction market agents.
|
5
5
|
Author: Gnosis
|
6
6
|
Requires-Python: >=3.10,<3.13
|
@@ -101,7 +101,8 @@ For example:
|
|
101
101
|
```python
|
102
102
|
import prediction_market_agent_tooling.benchmark.benchmark as bm
|
103
103
|
from prediction_market_agent_tooling.benchmark.agents import RandomAgent
|
104
|
-
from prediction_market_agent_tooling.markets.
|
104
|
+
from prediction_market_agent_tooling.markets.market_type import MarketType
|
105
|
+
from prediction_market_agent_tooling.markets.markets import get_binary_markets
|
105
106
|
|
106
107
|
benchmarker = bm.Benchmarker(
|
107
108
|
markets=get_binary_markets(limit=10, market_type=MarketType.MANIFOLD),
|
@@ -26,10 +26,10 @@ prediction_market_agent_tooling/benchmark/benchmark.py,sha256=hpIpjjePDFTLhK841s
|
|
26
26
|
prediction_market_agent_tooling/benchmark/utils.py,sha256=vmVTQLER8I7MM_bHFiavrNM9aQe28PL6WihM6J-E65k,3327
|
27
27
|
prediction_market_agent_tooling/chains.py,sha256=MF600uUR_I0Mf7-Pz5InS6RWMkdrZI2sohP6Vfh0YRw,148
|
28
28
|
prediction_market_agent_tooling/config.py,sha256=h9rsVMCDhDLMmH657CKEDZ4ZCWvC9RmX5p5kPI5rP58,13464
|
29
|
-
prediction_market_agent_tooling/data_download/langfuse_data_downloader.py,sha256=
|
30
|
-
prediction_market_agent_tooling/deploy/agent.py,sha256=
|
31
|
-
prediction_market_agent_tooling/deploy/agent_example.py,sha256=
|
32
|
-
prediction_market_agent_tooling/deploy/betting_strategy.py,sha256=
|
29
|
+
prediction_market_agent_tooling/data_download/langfuse_data_downloader.py,sha256=pPiZMp35CJ4YLv7KU4OMmkEJvzGQ_QobZmUONFOBAxs,14250
|
30
|
+
prediction_market_agent_tooling/deploy/agent.py,sha256=PKccRZPt9CTMLjbRjzI_XMx15843Bt4rXWSRtuovC9A,30901
|
31
|
+
prediction_market_agent_tooling/deploy/agent_example.py,sha256=B4bpv1JjOCJeHAWPCdyVY-BfEhRt6MfkVbYrhr0GZp4,1381
|
32
|
+
prediction_market_agent_tooling/deploy/betting_strategy.py,sha256=wMooHQ0C3Z4Pos5UhoS8QZNU4mygJDGdyAF5SUzMytw,29522
|
33
33
|
prediction_market_agent_tooling/deploy/constants.py,sha256=NzH0xk1D0PPSq67qlqpqeTHqwKYUvAn9_eBMhI-LNHc,446
|
34
34
|
prediction_market_agent_tooling/deploy/gcp/deploy.py,sha256=CYUgnfy-9XVk04kkxA_5yp0GE9Mw5caYqlFUZQ2j3ks,3739
|
35
35
|
prediction_market_agent_tooling/deploy/gcp/kubernetes_models.py,sha256=OsPboCFGiZKsvGyntGZHwdqPlLTthITkNF5rJFvGgU8,2582
|
@@ -52,26 +52,27 @@ prediction_market_agent_tooling/markets/manifold/data_models.py,sha256=3z1gFbPME
|
|
52
52
|
prediction_market_agent_tooling/markets/manifold/manifold.py,sha256=hHloNKYQRyd4OWTCUh5kCk-Kx1m77rOIg8d8bGJ6jvk,5454
|
53
53
|
prediction_market_agent_tooling/markets/manifold/utils.py,sha256=DCigEbpGWkXR-RZT_oJrvJhilmxKFAxcWMjUFi0nBBI,530
|
54
54
|
prediction_market_agent_tooling/markets/market_fees.py,sha256=YeK3ynjYIguB0xf6sO5iyg9lOdW_HD4C6nbJfiGyRCU,1351
|
55
|
-
prediction_market_agent_tooling/markets/
|
55
|
+
prediction_market_agent_tooling/markets/market_type.py,sha256=oIv6YQuiRsI7vCeNPiF-76dGePJb_ucCYjWurEq317w,2521
|
56
|
+
prediction_market_agent_tooling/markets/markets.py,sha256=xncpIFPbbrL-_Ae4luDadvbK3_KmafHIpaSQCALrt8Y,994
|
56
57
|
prediction_market_agent_tooling/markets/metaculus/api.py,sha256=4TRPGytQQbSdf42DCg2M_JWYPAuNjqZ3eBqaQBLkNks,2736
|
57
58
|
prediction_market_agent_tooling/markets/metaculus/data_models.py,sha256=WjPt0MKeJNtoY-8oLQTLC8vQYYQ-dBj8UZoPq-UBYsQ,3288
|
58
59
|
prediction_market_agent_tooling/markets/metaculus/metaculus.py,sha256=kM0U0k90YfLE82ra53JAoCR9uIc9wm4B8l32hLw5imU,5312
|
59
60
|
prediction_market_agent_tooling/markets/omen/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
60
61
|
prediction_market_agent_tooling/markets/omen/cow_contracts.py,sha256=sFaW82u_haL4nze8fjTmnQsOuV0OecunQlAhh1OAw0w,1091
|
61
62
|
prediction_market_agent_tooling/markets/omen/data_models.py,sha256=UcvwAMMlQSDkEoWQd73Rn0aAKswb9szWfNZVFaxpagM,31331
|
62
|
-
prediction_market_agent_tooling/markets/omen/omen.py,sha256=
|
63
|
+
prediction_market_agent_tooling/markets/omen/omen.py,sha256=yiJiVoGG_U3V8NsQzwAUiwA-yvbSXyzUcqJ8MYZYKj0,52783
|
63
64
|
prediction_market_agent_tooling/markets/omen/omen_constants.py,sha256=XtRk4vpxwUYkTndfjlcmghA-NOIneV8zdHFdyI7tHhM,487
|
64
65
|
prediction_market_agent_tooling/markets/omen/omen_contracts.py,sha256=0tzaL9P9T7whcTdgK1q_XsEKK3kzCAHs-eZEh-nTZEY,24105
|
65
|
-
prediction_market_agent_tooling/markets/omen/omen_resolving.py,sha256=
|
66
|
+
prediction_market_agent_tooling/markets/omen/omen_resolving.py,sha256=_vrnNhHT63-k0crE71OkjGaaYZ6fBX69q4nzcF0qv5k,11051
|
66
67
|
prediction_market_agent_tooling/markets/omen/omen_subgraph_handler.py,sha256=he3_xRLKaJQeEdP-VXuotAPM7rHRIJ4OE2mVWaixl7U,40134
|
67
68
|
prediction_market_agent_tooling/markets/polymarket/api.py,sha256=62PtOJyiXywRCvW4vnj5aq8XgQXqGP04GBW7o6XNQ8Y,5755
|
68
69
|
prediction_market_agent_tooling/markets/polymarket/clob_manager.py,sha256=sCCQw5GePrfike0A4EgQRtxaqp91RDjGaVWNx_5QzH4,5367
|
69
70
|
prediction_market_agent_tooling/markets/polymarket/constants.py,sha256=-sEFwEsMSJEgLAIaeJnWFoTBsnjSW_m5iKFiFkfw2NE,457
|
70
71
|
prediction_market_agent_tooling/markets/polymarket/data_models.py,sha256=a0PJVhW3b9IoUXunCIwxHm7W4KURkaNwwQU2y9nZtuU,5836
|
71
|
-
prediction_market_agent_tooling/markets/polymarket/polymarket.py,sha256
|
72
|
+
prediction_market_agent_tooling/markets/polymarket/polymarket.py,sha256=QKbmSflcK1lxDWyQ92VJxpKwSGJvoHvpRKepepMLeog,16669
|
72
73
|
prediction_market_agent_tooling/markets/polymarket/polymarket_contracts.py,sha256=x8yvAUPl55nbJALsQAAHJtstahhpH8WcEOj8or_QloQ,1165
|
73
|
-
prediction_market_agent_tooling/markets/polymarket/polymarket_subgraph_handler.py,sha256=
|
74
|
-
prediction_market_agent_tooling/markets/polymarket/utils.py,sha256=
|
74
|
+
prediction_market_agent_tooling/markets/polymarket/polymarket_subgraph_handler.py,sha256=6_dJbp9YBz0TZW6PxWGIB1L9VE-1JAIzvf8qTBrEyYs,2905
|
75
|
+
prediction_market_agent_tooling/markets/polymarket/utils.py,sha256=i1KjkQWABUoQyfX-XBuhACm6-POFMTXWifgP1V2sz-Y,1279
|
75
76
|
prediction_market_agent_tooling/markets/seer/data_models.py,sha256=nnuclpajQCkb_s52cCf_rwGWdgjMutaIPyfUq7CqX4M,7626
|
76
77
|
prediction_market_agent_tooling/markets/seer/exceptions.py,sha256=cEObdjluivD94tgOLzmimR7wgQEOt6SRakrYdhsRQtk,112
|
77
78
|
prediction_market_agent_tooling/markets/seer/price_manager.py,sha256=Sz8NkbDd5CYruKe6KZ9GU--Jf8FDSkniE-PVrbqGiPM,9952
|
@@ -82,7 +83,7 @@ prediction_market_agent_tooling/markets/seer/seer_subgraph_handler.py,sha256=nme
|
|
82
83
|
prediction_market_agent_tooling/markets/seer/subgraph_data_models.py,sha256=96v41jdNNxBqTCp5g8SLMSrIgeeITVx5IsBjVgm-qdo,2920
|
83
84
|
prediction_market_agent_tooling/markets/seer/swap_pool_handler.py,sha256=k_sCEJZLroVDjOVkZ084VKJGNODLGjBGezhsWEZvlH4,3528
|
84
85
|
prediction_market_agent_tooling/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
85
|
-
prediction_market_agent_tooling/tools/_generic_value.py,sha256=
|
86
|
+
prediction_market_agent_tooling/tools/_generic_value.py,sha256=L9SH_-JwD6RQeKoeTxvNWbkY6CxWIz-VjZEURXoZleg,10617
|
86
87
|
prediction_market_agent_tooling/tools/balances.py,sha256=Osab21btfJDw2Y-jT_TV-KHGrseCRxcsYeW6WcOMB8E,1050
|
87
88
|
prediction_market_agent_tooling/tools/betting_strategies/kelly_criterion.py,sha256=o5ba633gKiDqV4t_C2d9FWwH-HkRAOZd8FcZTYvbj6g,14451
|
88
89
|
prediction_market_agent_tooling/tools/betting_strategies/stretch_bet_between.py,sha256=THMXwFlskvzbjnX_OiYtDSzI8XVFyULWfP2525_9UGc,429
|
@@ -90,7 +91,8 @@ prediction_market_agent_tooling/tools/betting_strategies/utils.py,sha256=MpS3FOM
|
|
90
91
|
prediction_market_agent_tooling/tools/caches/db_cache.py,sha256=rZIGhgijquwwPtp_qncSAPR1SDF2XxIVZL1ir0fgzWw,12127
|
91
92
|
prediction_market_agent_tooling/tools/caches/inmemory_cache.py,sha256=ZW5iI5rmjqeAebu5T7ftRnlkxiL02IC-MxCfDB80x7w,1506
|
92
93
|
prediction_market_agent_tooling/tools/caches/serializers.py,sha256=vFDx4fsPxclXp2q0sv27j4al_M_Tj9aR2JJP-xNHQXA,2151
|
93
|
-
prediction_market_agent_tooling/tools/contract.py,sha256=
|
94
|
+
prediction_market_agent_tooling/tools/contract.py,sha256=Agd3eNsr9PW6t2jtGUzcQlmudNKpjvQkSfGEcq28i8k,33813
|
95
|
+
prediction_market_agent_tooling/tools/contract_utils.py,sha256=9X9raICUZkPDShilt02aYzS_ILZ62u0vG5081uWLdqk,2152
|
94
96
|
prediction_market_agent_tooling/tools/costs.py,sha256=EaAJ7v9laD4VEV3d8B44M4u3_oEO_H16jRVCdoZ93Uw,954
|
95
97
|
prediction_market_agent_tooling/tools/cow/cow_order.py,sha256=kdvhWVTb31oHVspQFowDNEIoDtx8hwGTlKsWYGRh3oQ,14050
|
96
98
|
prediction_market_agent_tooling/tools/cow/models.py,sha256=2hTW-Ye6SamBBAO32nVo4f3vjAOOySw8ehECReRcA3o,756
|
@@ -110,6 +112,7 @@ prediction_market_agent_tooling/tools/langfuse_.py,sha256=jI_4ROxqo41CCnWGS1vN_A
|
|
110
112
|
prediction_market_agent_tooling/tools/langfuse_client_utils.py,sha256=8d33dcYx5ElyE0pL_VTJTcJIXvt3PPkDaadQgxGGyp0,7132
|
111
113
|
prediction_market_agent_tooling/tools/omen/reality_accuracy.py,sha256=M1SF7iSW1gVlQSTskdVFTn09uPLST23YeipVIWj54io,2236
|
112
114
|
prediction_market_agent_tooling/tools/omen/sell_positions.py,sha256=Q4oI7_QI3AkyxlH10VvxDahYVrphQa1Wnox2Ce_cf_k,2452
|
115
|
+
prediction_market_agent_tooling/tools/openai_utils.py,sha256=0KqHp8QdJH8C5b-Sk62OYmB0f47AzmT4LkENs9m5Y8g,1164
|
113
116
|
prediction_market_agent_tooling/tools/parallelism.py,sha256=6Gou0hbjtMZrYvxjTDFUDZuxmE2nqZVbb6hkg1hF82A,1022
|
114
117
|
prediction_market_agent_tooling/tools/perplexity/perplexity_client.py,sha256=Oi5a_uaCAPtpTAEEVwD0SXWTsKkhCXOQjCBfa1eAuC0,3215
|
115
118
|
prediction_market_agent_tooling/tools/perplexity/perplexity_models.py,sha256=SfeR5FGQ2PqaxG4f4ij50LEnS9f2aeLplVwD7IZQh1s,820
|
@@ -121,6 +124,7 @@ prediction_market_agent_tooling/tools/rephrase.py,sha256=tqNqusaf5JeEC8ov11uL0Yz
|
|
121
124
|
prediction_market_agent_tooling/tools/safe.py,sha256=o477HGPQv7X_eDoOeYoELCHryiq1_102y_JVhGEPDXw,5165
|
122
125
|
prediction_market_agent_tooling/tools/singleton.py,sha256=CHpUJuu89Hwup2fH9CIChUwavc52TG6tCoi_wA_qZps,990
|
123
126
|
prediction_market_agent_tooling/tools/streamlit_user_login.py,sha256=NXEqfjT9Lc9QtliwSGRASIz1opjQ7Btme43H4qJbzgE,3010
|
127
|
+
prediction_market_agent_tooling/tools/streamlit_utils.py,sha256=CAHMsuHLUSE0ECLU1nnwvxPLyxGKBY4WqL2vjCvPzgw,6110
|
124
128
|
prediction_market_agent_tooling/tools/tavily/tavily_models.py,sha256=5ldQs1pZe6uJ5eDAuP4OLpzmcqYShlIV67kttNFvGS0,342
|
125
129
|
prediction_market_agent_tooling/tools/tavily/tavily_search.py,sha256=pPs0qZNfJ7G-1ajfz0iaWOBQyiC0TbcShfrW8T39jtg,3859
|
126
130
|
prediction_market_agent_tooling/tools/tokens/auto_deposit.py,sha256=E4jq6HvwOQCt6hb6yEFps7G78Ri5Z0JOfh3UqrwLPEM,9186
|
@@ -132,8 +136,8 @@ prediction_market_agent_tooling/tools/tokens/usd.py,sha256=DPO-4HBTy1-TZHKL_9CnH
|
|
132
136
|
prediction_market_agent_tooling/tools/transaction_cache.py,sha256=K5YKNL2_tR10Iw2TD9fuP-CTGpBbZtNdgbd0B_R7pjg,1814
|
133
137
|
prediction_market_agent_tooling/tools/utils.py,sha256=ruq6P5TFs8CBHxeBLj1Plpx7kuNFPpDgMsJGQgDiRNs,8785
|
134
138
|
prediction_market_agent_tooling/tools/web3_utils.py,sha256=CDbaidlLeQ4VHzSg150L7QNfHfGveljSePGuDVFEYqc,13963
|
135
|
-
prediction_market_agent_tooling-0.69.
|
136
|
-
prediction_market_agent_tooling-0.69.
|
137
|
-
prediction_market_agent_tooling-0.69.
|
138
|
-
prediction_market_agent_tooling-0.69.
|
139
|
-
prediction_market_agent_tooling-0.69.
|
139
|
+
prediction_market_agent_tooling-0.69.6.dist-info/LICENSE,sha256=6or154nLLU6bELzjh0mCreFjt0m2v72zLi3yHE0QbeE,7650
|
140
|
+
prediction_market_agent_tooling-0.69.6.dist-info/METADATA,sha256=YjLLuu8iU7HRDPHXtapKQeOpI8z4HWPS8Yb4640-TDE,8868
|
141
|
+
prediction_market_agent_tooling-0.69.6.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
142
|
+
prediction_market_agent_tooling-0.69.6.dist-info/entry_points.txt,sha256=m8PukHbeH5g0IAAmOf_1Ahm-sGAMdhSSRQmwtpmi2s8,81
|
143
|
+
prediction_market_agent_tooling-0.69.6.dist-info/RECORD,,
|
File without changes
|
File without changes
|