prediction-market-agent-tooling 0.60.5__py3-none-any.whl → 0.61.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/config.py +23 -8
- prediction_market_agent_tooling/deploy/agent.py +1 -0
- prediction_market_agent_tooling/markets/polymarket/utils.py +2 -2
- prediction_market_agent_tooling/tools/contract.py +2 -2
- prediction_market_agent_tooling/tools/google_utils.py +23 -27
- prediction_market_agent_tooling/tools/langfuse_client_utils.py +5 -1
- {prediction_market_agent_tooling-0.60.5.dist-info → prediction_market_agent_tooling-0.61.0.dist-info}/METADATA +1 -1
- {prediction_market_agent_tooling-0.60.5.dist-info → prediction_market_agent_tooling-0.61.0.dist-info}/RECORD +11 -11
- {prediction_market_agent_tooling-0.60.5.dist-info → prediction_market_agent_tooling-0.61.0.dist-info}/LICENSE +0 -0
- {prediction_market_agent_tooling-0.60.5.dist-info → prediction_market_agent_tooling-0.61.0.dist-info}/WHEEL +0 -0
- {prediction_market_agent_tooling-0.60.5.dist-info → prediction_market_agent_tooling-0.61.0.dist-info}/entry_points.txt +0 -0
@@ -3,7 +3,7 @@ import typing as t
|
|
3
3
|
from copy import deepcopy
|
4
4
|
|
5
5
|
from eth_account.signers.local import LocalAccount
|
6
|
-
from pydantic import
|
6
|
+
from pydantic import Field, model_validator
|
7
7
|
from pydantic.types import SecretStr
|
8
8
|
from pydantic.v1.types import SecretStr as SecretStrV1
|
9
9
|
from pydantic_settings import BaseSettings, SettingsConfigDict
|
@@ -39,10 +39,7 @@ class APIKeys(BaseSettings):
|
|
39
39
|
METACULUS_API_KEY: t.Optional[SecretStr] = None
|
40
40
|
METACULUS_USER_ID: t.Optional[int] = None
|
41
41
|
BET_FROM_PRIVATE_KEY: t.Optional[PrivateKey] = None
|
42
|
-
SAFE_ADDRESS:
|
43
|
-
ChecksumAddress | None,
|
44
|
-
BeforeValidator(lambda x: x if x is None else Web3.to_checksum_address(x)),
|
45
|
-
] = None
|
42
|
+
SAFE_ADDRESS: str | None = None
|
46
43
|
OPENAI_API_KEY: t.Optional[SecretStr] = None
|
47
44
|
GRAPH_API_KEY: t.Optional[SecretStr] = None
|
48
45
|
TENDERLY_FORK_RPC: t.Optional[str] = None
|
@@ -60,6 +57,8 @@ class APIKeys(BaseSettings):
|
|
60
57
|
PINATA_API_SECRET: t.Optional[SecretStr] = None
|
61
58
|
|
62
59
|
TAVILY_API_KEY: t.Optional[SecretStr] = None
|
60
|
+
# Don't get fooled! Serper and Serp are two different services.
|
61
|
+
SERPER_API_KEY: t.Optional[SecretStr] = None
|
63
62
|
|
64
63
|
SQLALCHEMY_DB_URL: t.Optional[SecretStr] = None
|
65
64
|
|
@@ -102,6 +101,18 @@ class APIKeys(BaseSettings):
|
|
102
101
|
data.SAFE_ADDRESS = None
|
103
102
|
return data
|
104
103
|
|
104
|
+
@property
|
105
|
+
def safe_address_checksum(self) -> ChecksumAddress | None:
|
106
|
+
return (
|
107
|
+
Web3.to_checksum_address(self.SAFE_ADDRESS) if self.SAFE_ADDRESS else None
|
108
|
+
)
|
109
|
+
|
110
|
+
@property
|
111
|
+
def serper_api_key(self) -> SecretStr:
|
112
|
+
return check_not_none(
|
113
|
+
self.SERPER_API_KEY, "SERPER_API_KEY missing in the environment."
|
114
|
+
)
|
115
|
+
|
105
116
|
@property
|
106
117
|
def manifold_user_id(self) -> str:
|
107
118
|
return get_authenticated_user(
|
@@ -140,7 +151,11 @@ class APIKeys(BaseSettings):
|
|
140
151
|
@property
|
141
152
|
def bet_from_address(self) -> ChecksumAddress:
|
142
153
|
"""If the SAFE is available, we always route transactions via SAFE. Otherwise we use the EOA."""
|
143
|
-
return
|
154
|
+
return (
|
155
|
+
self.safe_address_checksum
|
156
|
+
if self.safe_address_checksum
|
157
|
+
else self.public_key
|
158
|
+
)
|
144
159
|
|
145
160
|
@property
|
146
161
|
def openai_api_key(self) -> SecretStr:
|
@@ -249,10 +264,10 @@ class APIKeys(BaseSettings):
|
|
249
264
|
}
|
250
265
|
|
251
266
|
def check_if_is_safe_owner(self, ethereum_client: EthereumClient) -> bool:
|
252
|
-
if not self.
|
267
|
+
if not self.safe_address_checksum:
|
253
268
|
raise ValueError("Cannot check ownership if safe_address is not defined.")
|
254
269
|
|
255
|
-
s = SafeV141(self.
|
270
|
+
s = SafeV141(self.safe_address_checksum, ethereum_client)
|
256
271
|
public_key_from_signer = private_key_to_public_key(self.bet_from_private_key)
|
257
272
|
return s.retrieve_is_owner(public_key_from_signer)
|
258
273
|
|
@@ -3,7 +3,7 @@ from prediction_market_agent_tooling.markets.markets import MarketType
|
|
3
3
|
from prediction_market_agent_tooling.markets.polymarket.data_models_web import (
|
4
4
|
PolymarketFullMarket,
|
5
5
|
)
|
6
|
-
from prediction_market_agent_tooling.tools.google_utils import
|
6
|
+
from prediction_market_agent_tooling.tools.google_utils import search_google_gcp
|
7
7
|
|
8
8
|
|
9
9
|
def find_resolution_on_polymarket(question: str) -> Resolution | None:
|
@@ -35,7 +35,7 @@ def find_url_to_polymarket(question: str) -> str | None:
|
|
35
35
|
slug = "".join(replace_chars.get(char, char) for char in question.lower())
|
36
36
|
|
37
37
|
# Search for the links to the Polymarket's market page on Google.
|
38
|
-
links =
|
38
|
+
links = search_google_gcp(
|
39
39
|
# For some reason, just giving it in the query works better than using `site_search`, `exact_terms` or other parameters of the google search.
|
40
40
|
query=f"{MarketType.POLYMARKET.market_class.base_url} {question}",
|
41
41
|
num=10,
|
@@ -113,13 +113,13 @@ class ContractBaseClass(BaseModel):
|
|
113
113
|
Used for changing a state (writing) to the contract.
|
114
114
|
"""
|
115
115
|
|
116
|
-
if api_keys.
|
116
|
+
if api_keys.safe_address_checksum:
|
117
117
|
return send_function_on_contract_tx_using_safe(
|
118
118
|
web3=web3 or self.get_web3(),
|
119
119
|
contract_address=self.address,
|
120
120
|
contract_abi=self.abi,
|
121
121
|
from_private_key=api_keys.bet_from_private_key,
|
122
|
-
safe_address=api_keys.
|
122
|
+
safe_address=api_keys.safe_address_checksum,
|
123
123
|
function_name=function_name,
|
124
124
|
function_params=function_params,
|
125
125
|
tx_params=tx_params,
|
@@ -1,14 +1,11 @@
|
|
1
|
-
import json
|
2
1
|
import typing as t
|
3
2
|
from datetime import timedelta
|
4
3
|
|
4
|
+
import requests
|
5
5
|
import tenacity
|
6
|
-
from google.cloud import secretmanager
|
7
6
|
from googleapiclient.discovery import build
|
8
|
-
from pydantic import SecretStr
|
9
7
|
|
10
|
-
from prediction_market_agent_tooling.config import APIKeys
|
11
|
-
from prediction_market_agent_tooling.gtypes import PrivateKey
|
8
|
+
from prediction_market_agent_tooling.config import APIKeys
|
12
9
|
from prediction_market_agent_tooling.loggers import logger
|
13
10
|
from prediction_market_agent_tooling.tools.caches.db_cache import db_cache
|
14
11
|
|
@@ -16,10 +13,10 @@ from prediction_market_agent_tooling.tools.caches.db_cache import db_cache
|
|
16
13
|
@tenacity.retry(
|
17
14
|
wait=tenacity.wait_fixed(1),
|
18
15
|
stop=tenacity.stop_after_attempt(3),
|
19
|
-
after=lambda x: logger.debug(f"
|
16
|
+
after=lambda x: logger.debug(f"search_google_gcp failed, {x.attempt_number=}."),
|
20
17
|
)
|
21
18
|
@db_cache(max_age=timedelta(days=1))
|
22
|
-
def
|
19
|
+
def search_google_gcp(
|
23
20
|
query: str | None = None,
|
24
21
|
num: int = 3,
|
25
22
|
exact_terms: str | None = None,
|
@@ -57,24 +54,23 @@ def search_google(
|
|
57
54
|
raise ValueError(f"Can not parse results: {search}") from e
|
58
55
|
|
59
56
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
)
|
65
|
-
|
66
|
-
|
67
|
-
|
57
|
+
@tenacity.retry(
|
58
|
+
wait=tenacity.wait_fixed(1),
|
59
|
+
stop=tenacity.stop_after_attempt(3),
|
60
|
+
after=lambda x: logger.debug(f"search_google_serper failed, {x.attempt_number=}."),
|
61
|
+
)
|
62
|
+
@db_cache(max_age=timedelta(days=1))
|
63
|
+
def search_google_serper(q: str) -> list[str]:
|
64
|
+
"""Search Google using the Serper API."""
|
65
|
+
url = "https://google.serper.dev/search"
|
66
|
+
response = requests.post(
|
67
|
+
url,
|
68
|
+
headers={
|
69
|
+
"X-API-KEY": APIKeys().serper_api_key.get_secret_value(),
|
70
|
+
"Content-Type": "application/json",
|
71
|
+
},
|
72
|
+
json={"q": q},
|
68
73
|
)
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
else:
|
73
|
-
client = secretmanager.SecretManagerServiceClient()
|
74
|
-
name = f"projects/{project_id}/secrets/{secret_id}/versions/{version_id}"
|
75
|
-
response = client.access_secret_version(request={"name": name})
|
76
|
-
secret_payload = response.payload.data.decode("UTF-8")
|
77
|
-
secret_json = json.loads(secret_payload)
|
78
|
-
if "private_key" not in secret_json:
|
79
|
-
raise ValueError(f"Private key not found in gcp secret {secret_id}")
|
80
|
-
return PrivateKey(SecretStr(secret_json["private_key"]))
|
74
|
+
response.raise_for_status()
|
75
|
+
parsed = response.json()
|
76
|
+
return [x["link"] for x in parsed["organic"] if x.get("link")]
|
@@ -64,24 +64,28 @@ def get_traces_for_agent(
|
|
64
64
|
has_output: bool,
|
65
65
|
client: Langfuse,
|
66
66
|
to_timestamp: DatetimeUTC | None = None,
|
67
|
+
tags: str | list[str] | None = None,
|
67
68
|
) -> list[TraceWithDetails]:
|
68
69
|
"""
|
69
70
|
Fetch agent traces using pagination
|
70
71
|
"""
|
72
|
+
total_pages = -1
|
71
73
|
page = 1 # index starts from 1
|
72
74
|
all_agent_traces = []
|
73
75
|
while True:
|
74
|
-
logger.debug(f"
|
76
|
+
logger.debug(f"Fetching Langfuse page {page} / {total_pages}.")
|
75
77
|
traces = client.fetch_traces(
|
76
78
|
name=trace_name,
|
77
79
|
limit=100,
|
78
80
|
page=page,
|
79
81
|
from_timestamp=from_timestamp,
|
80
82
|
to_timestamp=to_timestamp,
|
83
|
+
tags=tags,
|
81
84
|
)
|
82
85
|
if not traces.data:
|
83
86
|
break
|
84
87
|
page += 1
|
88
|
+
total_pages = traces.meta.total_pages
|
85
89
|
|
86
90
|
agent_traces = [
|
87
91
|
t
|
@@ -20,8 +20,8 @@ prediction_market_agent_tooling/benchmark/__init__.py,sha256=47DEQpj8HBSa-_TImW-
|
|
20
20
|
prediction_market_agent_tooling/benchmark/agents.py,sha256=B1-uWdyeN4GGKMWGK_-CcAFJg1m9Y_XuaeIHPB29QR8,3971
|
21
21
|
prediction_market_agent_tooling/benchmark/benchmark.py,sha256=MqTiaaJ3cYiOLUVR7OyImLWxcEya3Rl5JyFYW-K0lwM,17097
|
22
22
|
prediction_market_agent_tooling/benchmark/utils.py,sha256=D0MfUkVZllmvcU0VOurk9tcKT7JTtwwOp-63zuCBVuc,2880
|
23
|
-
prediction_market_agent_tooling/config.py,sha256=
|
24
|
-
prediction_market_agent_tooling/deploy/agent.py,sha256=
|
23
|
+
prediction_market_agent_tooling/config.py,sha256=pZW8xsmPhAkhYE9XG8G3f9UIYlaoLSpZ9nv7MHxYpuo,10058
|
24
|
+
prediction_market_agent_tooling/deploy/agent.py,sha256=tMREXM2LwFsatbysCaNRvtCAyCNMAPMGgkkIEpCRj7g,25022
|
25
25
|
prediction_market_agent_tooling/deploy/agent_example.py,sha256=dIIdZashExWk9tOdyDjw87AuUcGyM7jYxNChYrVK2dM,1001
|
26
26
|
prediction_market_agent_tooling/deploy/betting_strategy.py,sha256=Y6Pb8OfSb6galRbfdNBvvNTgO-4dR2ybJ4o5GKJcMoM,12894
|
27
27
|
prediction_market_agent_tooling/deploy/constants.py,sha256=M5ty8URipYMGe_G-RzxRydK3AFL6CyvmqCraJUrLBnE,82
|
@@ -60,7 +60,7 @@ prediction_market_agent_tooling/markets/polymarket/api.py,sha256=UZ4_TG8ceb9Y-qg
|
|
60
60
|
prediction_market_agent_tooling/markets/polymarket/data_models.py,sha256=Fd5PI5y3mJM8VHExBhWFWEnuuIKxQmIAXgBuoPDvNjw,4341
|
61
61
|
prediction_market_agent_tooling/markets/polymarket/data_models_web.py,sha256=VZhVccTApygSKMmy6Au2G02JCJOKJnR_oVeKlaesuSg,12548
|
62
62
|
prediction_market_agent_tooling/markets/polymarket/polymarket.py,sha256=NRoZK71PtH8kkangMqme7twcAXhRJSSabbmOir-UnAI,3418
|
63
|
-
prediction_market_agent_tooling/markets/polymarket/utils.py,sha256=
|
63
|
+
prediction_market_agent_tooling/markets/polymarket/utils.py,sha256=8kTeVjXPcXC6DkDvWYsZQLY7x8DS6CEp_yznSEazsNU,2037
|
64
64
|
prediction_market_agent_tooling/markets/seer/data_models.py,sha256=HGJv4XSvCxXLLC5VwxZTZ5E4w_bWGKv50fM_6ssloxI,8203
|
65
65
|
prediction_market_agent_tooling/markets/seer/seer.py,sha256=r21sXj_4_oIG2L1N5l56vEYGI_q2RGem_6G-Sixkbck,12954
|
66
66
|
prediction_market_agent_tooling/markets/seer/seer_contracts.py,sha256=E7CYAKZiK6cg3dyj1kJuIPKSYYUft98F64shF5S0g4s,2730
|
@@ -83,14 +83,14 @@ prediction_market_agent_tooling/tools/betting_strategies/utils.py,sha256=kpIb-ci
|
|
83
83
|
prediction_market_agent_tooling/tools/caches/db_cache.py,sha256=dB8LNs2JvVRaFCeAKRmIQRwiirsMgtL31he8051wM-g,11431
|
84
84
|
prediction_market_agent_tooling/tools/caches/inmemory_cache.py,sha256=ZW5iI5rmjqeAebu5T7ftRnlkxiL02IC-MxCfDB80x7w,1506
|
85
85
|
prediction_market_agent_tooling/tools/caches/serializers.py,sha256=vFDx4fsPxclXp2q0sv27j4al_M_Tj9aR2JJP-xNHQXA,2151
|
86
|
-
prediction_market_agent_tooling/tools/contract.py,sha256=
|
86
|
+
prediction_market_agent_tooling/tools/contract.py,sha256=XM7v6Wmi5OXPtn0SS__27MhlaBHGJG3VEeQFSIBJo6U,20963
|
87
87
|
prediction_market_agent_tooling/tools/costs.py,sha256=EaAJ7v9laD4VEV3d8B44M4u3_oEO_H16jRVCdoZ93Uw,954
|
88
88
|
prediction_market_agent_tooling/tools/cow/cow_manager.py,sha256=WK6Uk722VotjLHtxDPHxvwBrWVb3rvTegg_3w58ehwU,3869
|
89
89
|
prediction_market_agent_tooling/tools/cow/cow_order.py,sha256=M3zQohgAzy_LETnf9rKtS1L9rr7FP92CH6v0G2laZkM,4435
|
90
90
|
prediction_market_agent_tooling/tools/custom_exceptions.py,sha256=Fh8z1fbwONvP4-j7AmV_PuEcoqb6-QXa9PJ9m7guMcM,93
|
91
91
|
prediction_market_agent_tooling/tools/datetime_utc.py,sha256=8_WackjtjC8zHXrhQFTGQ6e6Fz_6llWoKR4CSFvIv9I,2766
|
92
92
|
prediction_market_agent_tooling/tools/db/db_manager.py,sha256=GtzHH1NLl8HwqC8Z7s6eTlIQXuV0blxfaV2PeQrBnfQ,3013
|
93
|
-
prediction_market_agent_tooling/tools/google_utils.py,sha256=
|
93
|
+
prediction_market_agent_tooling/tools/google_utils.py,sha256=D-6FB2HRtmxaKZJ_Za-qj6VZCp5XU18rF4wLMMrqEUg,2557
|
94
94
|
prediction_market_agent_tooling/tools/hexbytes_custom.py,sha256=ytwr4N8t-9UF1F4wXsln3IV1HBKgaYirsErc3NsKL-M,2119
|
95
95
|
prediction_market_agent_tooling/tools/httpx_cached_client.py,sha256=RxD-hwtZCMctnMwfzy8t51W9Z9gxFGtDYxBIMChazpc,406
|
96
96
|
prediction_market_agent_tooling/tools/image_gen/image_gen.py,sha256=HzRwBx62hOXBOmrtpkXaP9Qq1Ku03uUGdREocyjLQ_k,1266
|
@@ -99,7 +99,7 @@ prediction_market_agent_tooling/tools/ipfs/ipfs_handler.py,sha256=CTTMfTvs_8PH4k
|
|
99
99
|
prediction_market_agent_tooling/tools/is_invalid.py,sha256=TAHQXiiusAU45xJ11ZyEP7PnEfcjfzVG7qHRbsHiAd0,5335
|
100
100
|
prediction_market_agent_tooling/tools/is_predictable.py,sha256=qVd6zqay2Dg2fyeAuZvAFqSHMg71TcPfCZULsVk2XvA,6797
|
101
101
|
prediction_market_agent_tooling/tools/langfuse_.py,sha256=jI_4ROxqo41CCnWGS1vN_AeDVhRzLMaQLxH3kxDu3L8,1153
|
102
|
-
prediction_market_agent_tooling/tools/langfuse_client_utils.py,sha256=
|
102
|
+
prediction_market_agent_tooling/tools/langfuse_client_utils.py,sha256=IQboU9EPl4QEIo0poNylomevuVntpPpmkuNCzZl1Qdg,6058
|
103
103
|
prediction_market_agent_tooling/tools/omen/reality_accuracy.py,sha256=M1SF7iSW1gVlQSTskdVFTn09uPLST23YeipVIWj54io,2236
|
104
104
|
prediction_market_agent_tooling/tools/omen/sell_positions.py,sha256=hZCxXpcACO95DyiZ5oLFp982N0erZg4wccdSUKTgRlA,2307
|
105
105
|
prediction_market_agent_tooling/tools/parallelism.py,sha256=6Gou0hbjtMZrYvxjTDFUDZuxmE2nqZVbb6hkg1hF82A,1022
|
@@ -117,8 +117,8 @@ prediction_market_agent_tooling/tools/tokens/main_token.py,sha256=7JPgVF4RbiFzLD
|
|
117
117
|
prediction_market_agent_tooling/tools/transaction_cache.py,sha256=K5YKNL2_tR10Iw2TD9fuP-CTGpBbZtNdgbd0B_R7pjg,1814
|
118
118
|
prediction_market_agent_tooling/tools/utils.py,sha256=jLG4nbEoIzzJiZ4RgMx4Q969Zdl0p0s63p8uET_0Fuw,6440
|
119
119
|
prediction_market_agent_tooling/tools/web3_utils.py,sha256=3wfqNxvMn44ivweFRoeKNVb9QRtFd7kFtp7VUY5juEE,12862
|
120
|
-
prediction_market_agent_tooling-0.
|
121
|
-
prediction_market_agent_tooling-0.
|
122
|
-
prediction_market_agent_tooling-0.
|
123
|
-
prediction_market_agent_tooling-0.
|
124
|
-
prediction_market_agent_tooling-0.
|
120
|
+
prediction_market_agent_tooling-0.61.0.dist-info/LICENSE,sha256=6or154nLLU6bELzjh0mCreFjt0m2v72zLi3yHE0QbeE,7650
|
121
|
+
prediction_market_agent_tooling-0.61.0.dist-info/METADATA,sha256=Dj083O-3F_h45GoO99u4jvmNKsgeaLGnrB869GRE1Gk,8629
|
122
|
+
prediction_market_agent_tooling-0.61.0.dist-info/WHEEL,sha256=XbeZDeTWKc1w7CSIyre5aMDU_-PohRwTQceYnisIYYY,88
|
123
|
+
prediction_market_agent_tooling-0.61.0.dist-info/entry_points.txt,sha256=m8PukHbeH5g0IAAmOf_1Ahm-sGAMdhSSRQmwtpmi2s8,81
|
124
|
+
prediction_market_agent_tooling-0.61.0.dist-info/RECORD,,
|
File without changes
|
File without changes
|