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.
@@ -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 BeforeValidator, Field, model_validator
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: t.Annotated[
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 self.SAFE_ADDRESS if self.SAFE_ADDRESS else self.public_key
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.SAFE_ADDRESS:
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.SAFE_ADDRESS, ethereum_client)
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
 
@@ -106,6 +106,7 @@ class DeployableAgent:
106
106
  ) -> None:
107
107
  self.start_time = utcnow()
108
108
  self.enable_langfuse = enable_langfuse
109
+ self.api_keys = APIKeys()
109
110
  self.initialize_langfuse()
110
111
  self.load()
111
112
 
@@ -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 search_google
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 = search_google(
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.SAFE_ADDRESS:
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.SAFE_ADDRESS,
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, CloudCredentials
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"search_google failed, {x.attempt_number=}."),
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 search_google(
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
- def get_private_key_from_gcp_secret(
61
- secret_id: str,
62
- project_id: str = "582587111398", # Gnosis AI default project_id
63
- version_id: str = "latest",
64
- ) -> PrivateKey:
65
- # If credentials filename specified, use that, else read using default credentials path.
66
- google_application_credentials_filename = (
67
- CloudCredentials().GOOGLE_APPLICATION_CREDENTIALS
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
- if google_application_credentials_filename is not None:
70
- # mypy interprets incorrectly that from_service_account_json requires further args.
71
- client = secretmanager.SecretManagerServiceClient.from_service_account_json(filename=google_application_credentials_filename) # type: ignore [call-arg]
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"fetching page {page}")
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
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: prediction-market-agent-tooling
3
- Version: 0.60.5
3
+ Version: 0.61.0
4
4
  Summary: Tools to benchmark, deploy and monitor prediction market agents.
5
5
  Author: Gnosis
6
6
  Requires-Python: >=3.10,<3.13
@@ -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=eiJPhb736Jtgrbh2d035_bFz2YaIiipUPapgIjYNqM4,9629
24
- prediction_market_agent_tooling/deploy/agent.py,sha256=tC0MQKR_63SdsfDrCWXAko0yP01zvP7tuspAbjCj0eE,24988
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=DImFxeMg8lTfsEDZ8FavndW38TfUsCkawcVGnucsuGo,2029
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=BCl3R-n5jpp5XPAho9yTuUxRbOoKbZSga1Qaa4RfAp8,20945
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=t3_UEEvKX3L0biSIQ560GdRbllQ6eprhK_upE243A-0,3185
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=83T31s-YbsnNBLyYCjmBI2BBKUEqJUuYFa0uCdkoqy8,5901
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.60.5.dist-info/LICENSE,sha256=6or154nLLU6bELzjh0mCreFjt0m2v72zLi3yHE0QbeE,7650
121
- prediction_market_agent_tooling-0.60.5.dist-info/METADATA,sha256=Mx8hYXaIMNmbl5cRGcdZDhBeosJAmKHqfKL3xhElrZg,8629
122
- prediction_market_agent_tooling-0.60.5.dist-info/WHEEL,sha256=XbeZDeTWKc1w7CSIyre5aMDU_-PohRwTQceYnisIYYY,88
123
- prediction_market_agent_tooling-0.60.5.dist-info/entry_points.txt,sha256=m8PukHbeH5g0IAAmOf_1Ahm-sGAMdhSSRQmwtpmi2s8,81
124
- prediction_market_agent_tooling-0.60.5.dist-info/RECORD,,
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,,