prediction-market-agent-tooling 0.55.0__py3-none-any.whl → 0.55.1__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.
@@ -1,10 +1,10 @@
1
1
  import typing as t
2
2
 
3
- from gnosis.eth import EthereumClient
4
- from gnosis.safe import Safe
5
3
  from pydantic.types import SecretStr
6
4
  from pydantic.v1.types import SecretStr as SecretStrV1
7
5
  from pydantic_settings import BaseSettings, SettingsConfigDict
6
+ from safe_eth.eth import EthereumClient
7
+ from safe_eth.safe.safe import SafeV141
8
8
 
9
9
  from prediction_market_agent_tooling.gtypes import (
10
10
  ChecksumAddress,
@@ -200,6 +200,6 @@ class APIKeys(BaseSettings):
200
200
  if not self.SAFE_ADDRESS:
201
201
  raise ValueError("Cannot check ownership if safe_address is not defined.")
202
202
 
203
- s = Safe(self.SAFE_ADDRESS, ethereum_client) # type: ignore[abstract]
203
+ s = SafeV141(self.SAFE_ADDRESS, ethereum_client)
204
204
  public_key_from_signer = private_key_to_public_key(self.bet_from_private_key)
205
205
  return s.retrieve_is_owner(public_key_from_signer)
@@ -30,6 +30,10 @@ from prediction_market_agent_tooling.deploy.gcp.utils import (
30
30
  gcp_function_is_active,
31
31
  gcp_resolve_api_keys_secrets,
32
32
  )
33
+ from prediction_market_agent_tooling.deploy.trade_interval import (
34
+ FixedInterval,
35
+ TradeInterval,
36
+ )
33
37
  from prediction_market_agent_tooling.gtypes import xDai, xdai_type
34
38
  from prediction_market_agent_tooling.loggers import logger
35
39
  from prediction_market_agent_tooling.markets.agent_market import (
@@ -279,9 +283,10 @@ def {entrypoint_function_name}(request) -> str:
279
283
 
280
284
  class DeployablePredictionAgent(DeployableAgent):
281
285
  bet_on_n_markets_per_run: int = 1
286
+ n_markets_to_fetch: int = MAX_AVAILABLE_MARKETS
282
287
  min_balance_to_keep_in_native_currency: xDai | None = xdai_type(0.1)
283
288
  allow_invalid_questions: bool = False
284
- same_market_bet_interval: timedelta = timedelta(hours=24)
289
+ same_market_trade_interval: TradeInterval = FixedInterval(timedelta(hours=24))
285
290
  # Only Metaculus allows to post predictions without trading (buying/selling of outcome tokens).
286
291
  supported_markets: t.Sequence[MarketType] = [MarketType.METACULUS]
287
292
 
@@ -345,7 +350,9 @@ class DeployablePredictionAgent(DeployableAgent):
345
350
  Subclasses can implement their own logic instead of this one, or on top of this one.
346
351
  By default, it allows only markets where user didn't bet recently and it's a reasonable question.
347
352
  """
348
- if self.have_bet_on_market_since(market, since=self.same_market_bet_interval):
353
+ if self.have_bet_on_market_since(
354
+ market, since=self.same_market_trade_interval.get(market=market)
355
+ ):
349
356
  return False
350
357
 
351
358
  # Manifold allows to bet only on markets with probability between 1 and 99.
@@ -370,14 +377,13 @@ class DeployablePredictionAgent(DeployableAgent):
370
377
  def get_markets(
371
378
  self,
372
379
  market_type: MarketType,
373
- limit: int = MAX_AVAILABLE_MARKETS,
374
380
  sort_by: SortBy = SortBy.CLOSING_SOONEST,
375
381
  filter_by: FilterBy = FilterBy.OPEN,
376
382
  ) -> t.Sequence[AgentMarket]:
377
383
  cls = market_type.market_class
378
384
  # Fetch the soonest closing markets to choose from
379
385
  available_markets = cls.get_binary_markets(
380
- limit=limit, sort_by=sort_by, filter_by=filter_by
386
+ limit=self.n_markets_to_fetch, sort_by=sort_by, filter_by=filter_by
381
387
  )
382
388
  return available_markets
383
389
 
@@ -0,0 +1,46 @@
1
+ from abc import ABC, abstractmethod
2
+ from datetime import timedelta
3
+
4
+ from prediction_market_agent_tooling.markets.agent_market import AgentMarket
5
+ from prediction_market_agent_tooling.tools.utils import check_not_none
6
+
7
+
8
+ class TradeInterval(ABC):
9
+ @abstractmethod
10
+ def get(
11
+ self,
12
+ market: AgentMarket,
13
+ ) -> timedelta:
14
+ raise NotImplementedError("Subclass should implement this.")
15
+
16
+
17
+ class FixedInterval(TradeInterval):
18
+ """
19
+ For trades at a fixed interval.
20
+ """
21
+
22
+ def __init__(self, interval: timedelta):
23
+ self.interval = interval
24
+
25
+ def get(
26
+ self,
27
+ market: AgentMarket,
28
+ ) -> timedelta:
29
+ return self.interval
30
+
31
+
32
+ class MarketLifetimeProportionalInterval(TradeInterval):
33
+ """
34
+ For uniformly distributed trades over the market's lifetime.
35
+ """
36
+
37
+ def __init__(self, max_trades: int):
38
+ self.max_trades = max_trades
39
+
40
+ def get(
41
+ self,
42
+ market: AgentMarket,
43
+ ) -> timedelta:
44
+ created_time = check_not_none(market.created_time)
45
+ close_time = check_not_none(market.close_time)
46
+ return (close_time - created_time) / self.max_trades
@@ -0,0 +1,44 @@
1
+ from pydantic import BaseModel, Field
2
+
3
+ from prediction_market_agent_tooling.tools.tavily.tavily_models import TavilyResult
4
+
5
+
6
+ class RelevantNewsAnalysis(BaseModel):
7
+ reasoning: str = Field(
8
+ ...,
9
+ description="The reason why the news contains information relevant to the given question. Or if no news is relevant, why not.",
10
+ )
11
+ contains_relevant_news: bool = Field(
12
+ ...,
13
+ description="A boolean flag for whether the news contains information relevant to the given question.",
14
+ )
15
+
16
+
17
+ class RelevantNews(BaseModel):
18
+ question: str
19
+ url: str
20
+ summary: str
21
+ relevance_reasoning: str
22
+ days_ago: int
23
+
24
+ @staticmethod
25
+ def from_tavily_result_and_analysis(
26
+ question: str,
27
+ days_ago: int,
28
+ tavily_result: TavilyResult,
29
+ relevant_news_analysis: RelevantNewsAnalysis,
30
+ ) -> "RelevantNews":
31
+ return RelevantNews(
32
+ question=question,
33
+ url=tavily_result.url,
34
+ summary=tavily_result.content,
35
+ relevance_reasoning=relevant_news_analysis.reasoning,
36
+ days_ago=days_ago,
37
+ )
38
+
39
+
40
+ class NoRelevantNews(BaseModel):
41
+ """
42
+ A placeholder model for when no relevant news is found. Enables ability to
43
+ distinguish between 'a cache hit with no news' and 'a cache miss'.
44
+ """
@@ -0,0 +1,162 @@
1
+ from datetime import datetime, timedelta
2
+
3
+ from langchain_core.output_parsers import PydanticOutputParser
4
+ from langchain_core.prompts import PromptTemplate
5
+ from langchain_openai import ChatOpenAI
6
+
7
+ from prediction_market_agent_tooling.config import APIKeys
8
+ from prediction_market_agent_tooling.tools.langfuse_ import (
9
+ get_langfuse_langchain_config,
10
+ observe,
11
+ )
12
+ from prediction_market_agent_tooling.tools.relevant_news_analysis.data_models import (
13
+ NoRelevantNews,
14
+ RelevantNews,
15
+ RelevantNewsAnalysis,
16
+ )
17
+ from prediction_market_agent_tooling.tools.relevant_news_analysis.relevant_news_cache import (
18
+ RelevantNewsResponseCache,
19
+ )
20
+ from prediction_market_agent_tooling.tools.tavily.tavily_search import (
21
+ get_relevant_news_since,
22
+ )
23
+ from prediction_market_agent_tooling.tools.tavily.tavily_storage import TavilyStorage
24
+ from prediction_market_agent_tooling.tools.utils import check_not_none, utcnow
25
+
26
+ SUMMARISE_RELEVANT_NEWS_PROMPT_TEMPLATE = """
27
+ You are an expert news analyst, tracking stories that may affect your prediction to the outcome of a particular QUESTION.
28
+
29
+ Your role is to identify only the relevant information from a scraped news site (RAW_CONTENT), analyse it, and determine whether it contains developments or announcements occurring **after** the DATE_OF_INTEREST that could affect the outcome of the QUESTION.
30
+
31
+ Note that the news article may be published after the DATE_OF_INTEREST, but reference information that is older than the DATE_OF_INTEREST.
32
+
33
+ [QUESTION]
34
+ {question}
35
+
36
+ [DATE_OF_INTEREST]
37
+ {date_of_interest}
38
+
39
+ [RAW_CONTENT]
40
+ {raw_content}
41
+
42
+ For your analysis, you should:
43
+ - Discard the 'noise' from the raw content (e.g. ads, irrelevant content)
44
+ - Consider ONLY information that would have a notable impact on the outcome of the question.
45
+ - Consider ONLY information relating to an announcement or development that occurred **after** the DATE_OF_INTEREST.
46
+ - Present this information concisely in your reasoning.
47
+ - In your reasoning, do not use the term 'DATE_OF_INTEREST' directly. Use the actual date you are referring to instead.
48
+ - In your reasoning, do not use the term 'RAW_CONTENT' directly. Refer to it as 'the article', or quote the content you are referring to.
49
+
50
+ {format_instructions}
51
+ """
52
+
53
+
54
+ @observe()
55
+ def analyse_news_relevance(
56
+ raw_content: str,
57
+ question: str,
58
+ date_of_interest: datetime,
59
+ model: str,
60
+ temperature: float,
61
+ ) -> RelevantNewsAnalysis:
62
+ """
63
+ Analyse whether the news contains new (relative to the given date)
64
+ information relevant to the given question.
65
+ """
66
+ parser = PydanticOutputParser(pydantic_object=RelevantNewsAnalysis)
67
+ prompt = PromptTemplate(
68
+ template=SUMMARISE_RELEVANT_NEWS_PROMPT_TEMPLATE,
69
+ input_variables=["question", "date_of_interest", "raw_content"],
70
+ partial_variables={"format_instructions": parser.get_format_instructions()},
71
+ )
72
+ llm = ChatOpenAI(
73
+ temperature=temperature,
74
+ model=model,
75
+ api_key=APIKeys().openai_api_key_secretstr_v1,
76
+ )
77
+ chain = prompt | llm | parser
78
+
79
+ relevant_news_analysis: RelevantNewsAnalysis = chain.invoke(
80
+ {
81
+ "raw_content": raw_content,
82
+ "question": question,
83
+ "date_of_interest": str(date_of_interest),
84
+ },
85
+ config=get_langfuse_langchain_config(),
86
+ )
87
+ return relevant_news_analysis
88
+
89
+
90
+ @observe()
91
+ def get_certified_relevant_news_since(
92
+ question: str,
93
+ days_ago: int,
94
+ tavily_storage: TavilyStorage | None = None,
95
+ ) -> RelevantNews | None:
96
+ """
97
+ Get relevant news since a given date for a given question. Retrieves
98
+ possibly relevant news from tavily, then checks that it is relevant via
99
+ an LLM call.
100
+ """
101
+ results = get_relevant_news_since(
102
+ question=question,
103
+ days_ago=days_ago,
104
+ score_threshold=0.0, # Be conservative to avoid missing relevant information
105
+ max_results=3, # A tradeoff between cost and quality. 3 seems to be a good balance.
106
+ tavily_storage=tavily_storage,
107
+ )
108
+
109
+ # Sort results by descending 'relevance score' to maximise the chance of
110
+ # finding relevant news early
111
+ results = sorted(
112
+ results,
113
+ key=lambda result: result.score,
114
+ reverse=True,
115
+ )
116
+
117
+ for result in results:
118
+ relevant_news_analysis = analyse_news_relevance(
119
+ raw_content=check_not_none(result.raw_content),
120
+ question=question,
121
+ date_of_interest=utcnow() - timedelta(days=days_ago),
122
+ model="gpt-4o", # 4o-mini isn't good enough, 1o and 1o-mini are too expensive
123
+ temperature=0.0,
124
+ )
125
+
126
+ # Return first relevant news found
127
+ if relevant_news_analysis.contains_relevant_news:
128
+ return RelevantNews.from_tavily_result_and_analysis(
129
+ question=question,
130
+ days_ago=days_ago,
131
+ tavily_result=result,
132
+ relevant_news_analysis=relevant_news_analysis,
133
+ )
134
+
135
+ # No relevant news found
136
+ return None
137
+
138
+
139
+ def get_certified_relevant_news_since_cached(
140
+ question: str,
141
+ days_ago: int,
142
+ cache: RelevantNewsResponseCache,
143
+ tavily_storage: TavilyStorage | None = None,
144
+ ) -> RelevantNews | None:
145
+ cached = cache.find(question=question, days_ago=days_ago)
146
+
147
+ if isinstance(cached, NoRelevantNews):
148
+ return None
149
+ elif cached is None:
150
+ relevant_news = get_certified_relevant_news_since(
151
+ question=question,
152
+ days_ago=days_ago,
153
+ tavily_storage=tavily_storage,
154
+ )
155
+ cache.save(
156
+ question=question,
157
+ days_ago=days_ago,
158
+ relevant_news=relevant_news,
159
+ )
160
+ return relevant_news
161
+ else:
162
+ return cached
@@ -0,0 +1,90 @@
1
+ from datetime import datetime, timedelta
2
+
3
+ from pydantic import ValidationError
4
+ from sqlmodel import Field, Session, SQLModel, create_engine, desc, select
5
+
6
+ from prediction_market_agent_tooling.config import APIKeys
7
+ from prediction_market_agent_tooling.loggers import logger
8
+ from prediction_market_agent_tooling.tools.relevant_news_analysis.data_models import (
9
+ NoRelevantNews,
10
+ RelevantNews,
11
+ )
12
+ from prediction_market_agent_tooling.tools.utils import utcnow
13
+
14
+
15
+ class RelevantNewsCacheModel(SQLModel, table=True):
16
+ __tablename__ = "relevant_news_response_cache"
17
+ __table_args__ = {"extend_existing": True}
18
+ id: int | None = Field(default=None, primary_key=True)
19
+ question: str = Field(index=True)
20
+ datetime_: datetime = Field(index=True)
21
+ days_ago: int
22
+ json_dump: str | None
23
+
24
+
25
+ class RelevantNewsResponseCache:
26
+ def __init__(self, sqlalchemy_db_url: str | None = None):
27
+ self.engine = create_engine(
28
+ sqlalchemy_db_url
29
+ if sqlalchemy_db_url
30
+ else APIKeys().sqlalchemy_db_url.get_secret_value()
31
+ )
32
+ self._initialize_db()
33
+
34
+ def _initialize_db(self) -> None:
35
+ """
36
+ Creates the tables if they don't exist
37
+ """
38
+ with self.engine.connect() as conn:
39
+ SQLModel.metadata.create_all(
40
+ conn,
41
+ tables=[SQLModel.metadata.tables[RelevantNewsCacheModel.__tablename__]],
42
+ )
43
+
44
+ def find(
45
+ self,
46
+ question: str,
47
+ days_ago: int,
48
+ ) -> RelevantNews | NoRelevantNews | None:
49
+ with Session(self.engine) as session:
50
+ query = (
51
+ select(RelevantNewsCacheModel)
52
+ .where(RelevantNewsCacheModel.question == question)
53
+ .where(RelevantNewsCacheModel.days_ago <= days_ago)
54
+ .where(
55
+ RelevantNewsCacheModel.datetime_ >= utcnow() - timedelta(days=1)
56
+ ) # Cache entries expire after 1 day
57
+ )
58
+ item = session.exec(
59
+ query.order_by(desc(RelevantNewsCacheModel.datetime_))
60
+ ).first()
61
+
62
+ if item is None:
63
+ return None
64
+ else:
65
+ if item.json_dump is None:
66
+ return NoRelevantNews()
67
+ else:
68
+ try:
69
+ return RelevantNews.model_validate_json(item.json_dump)
70
+ except ValidationError as e:
71
+ logger.error(
72
+ f"Error deserializing RelevantNews from cache for {question=}, {days_ago=} and {item=}: {e}"
73
+ )
74
+ return None
75
+
76
+ def save(
77
+ self,
78
+ question: str,
79
+ days_ago: int,
80
+ relevant_news: RelevantNews | None,
81
+ ) -> None:
82
+ with Session(self.engine) as session:
83
+ cached = RelevantNewsCacheModel(
84
+ question=question,
85
+ days_ago=days_ago,
86
+ datetime_=utcnow(), # Assumes that the cache is being updated at the time the news is found
87
+ json_dump=relevant_news.model_dump_json() if relevant_news else None,
88
+ )
89
+ session.add(cached)
90
+ session.commit()
@@ -1,16 +1,16 @@
1
1
  from eth_account.signers.local import LocalAccount
2
2
  from eth_typing import ChecksumAddress
3
- from gnosis.eth import EthereumClient
4
- from gnosis.eth.constants import NULL_ADDRESS
5
- from gnosis.eth.contracts import get_safe_V1_4_1_contract
6
- from gnosis.safe.proxy_factory import ProxyFactoryV141
7
- from gnosis.safe.safe import Safe
8
3
  from safe_cli.safe_addresses import (
9
4
  get_default_fallback_handler_address,
10
5
  get_proxy_factory_address,
11
6
  get_safe_contract_address,
12
7
  get_safe_l2_contract_address,
13
8
  )
9
+ from safe_eth.eth import EthereumClient
10
+ from safe_eth.eth.constants import NULL_ADDRESS
11
+ from safe_eth.eth.contracts import get_safe_V1_4_1_contract
12
+ from safe_eth.safe.proxy_factory import ProxyFactoryV141
13
+ from safe_eth.safe.safe import SafeV141
14
14
  from web3.types import Wei
15
15
 
16
16
  from prediction_market_agent_tooling.loggers import logger
@@ -87,7 +87,7 @@ def create_safe(
87
87
 
88
88
  # We ignore mypy below because using the proper class SafeV141 yields an error and mypy
89
89
  # doesn't understand that there is a hacky factory method (__new__) on this abstract class.
90
- safe_version = Safe(safe_contract_address, ethereum_client).retrieve_version() # type: ignore
90
+ safe_version = SafeV141(safe_contract_address, ethereum_client).retrieve_version()
91
91
  logger.info(
92
92
  f"Safe-master-copy={safe_contract_address} version={safe_version}\n"
93
93
  f"Fallback-handler={fallback_handler}\n"
@@ -129,7 +129,7 @@ def _tavily_search(
129
129
  return response
130
130
 
131
131
 
132
- def get_related_news_since(
132
+ def get_relevant_news_since(
133
133
  question: str,
134
134
  days_ago: int,
135
135
  score_threshold: float = DEFAULT_SCORE_THRESHOLD,
@@ -5,9 +5,9 @@ import base58
5
5
  import tenacity
6
6
  from eth_account import Account
7
7
  from eth_typing import URI
8
- from gnosis.eth import EthereumClient
9
- from gnosis.safe.safe import Safe
10
8
  from pydantic.types import SecretStr
9
+ from safe_eth.eth import EthereumClient
10
+ from safe_eth.safe.safe import SafeV141
11
11
  from web3 import Web3
12
12
  from web3.constants import HASH_ZERO
13
13
  from web3.types import AccessList, AccessListEntry, Nonce, TxParams, TxReceipt, Wei
@@ -200,7 +200,7 @@ def send_function_on_contract_tx(
200
200
  # Don't retry on `reverted` messages, as they would always fail again.
201
201
  retry=tenacity.retry_if_exception_message(match=NOT_REVERTED_ICASE_REGEX_PATTERN),
202
202
  wait=tenacity.wait_chain(*[tenacity.wait_fixed(n) for n in range(1, 10)]),
203
- stop=tenacity.stop_after_attempt(9),
203
+ stop=tenacity.stop_after_attempt(5),
204
204
  after=lambda x: logger.debug(
205
205
  f"send_function_on_contract_tx_using_safe failed, {x.attempt_number=}."
206
206
  ),
@@ -219,7 +219,7 @@ def send_function_on_contract_tx_using_safe(
219
219
  if not web3.provider.endpoint_uri: # type: ignore
220
220
  raise EnvironmentError("RPC_URL not available in web3 object.")
221
221
  ethereum_client = EthereumClient(ethereum_node_url=URI(web3.provider.endpoint_uri)) # type: ignore
222
- s = Safe(safe_address, ethereum_client) # type: ignore
222
+ s = SafeV141(safe_address, ethereum_client)
223
223
  safe_master_copy_address = s.retrieve_master_copy_address()
224
224
  eoa_public_key = private_key_to_public_key(from_private_key)
225
225
  # See https://ethereum.stackexchange.com/questions/123750/how-to-implement-eip-2930-access-list for details,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: prediction-market-agent-tooling
3
- Version: 0.55.0
3
+ Version: 0.55.1
4
4
  Summary: Tools to benchmark, deploy and monitor prediction market agents.
5
5
  Author: Gnosis
6
6
  Requires-Python: >=3.10,<3.12
@@ -38,7 +38,7 @@ Requires-Dist: pydantic-settings (>=2.4.0,<3.0.0)
38
38
  Requires-Dist: pymongo (>=4.8.0,<5.0.0)
39
39
  Requires-Dist: python-dateutil (>=2.9.0.post0,<3.0.0)
40
40
  Requires-Dist: safe-cli (>=1.0.0,<2.0.0)
41
- Requires-Dist: safe-eth-py (>=6.0.0b14,<7.0.0)
41
+ Requires-Dist: safe-eth-py (>=6.0.0b41,<7.0.0)
42
42
  Requires-Dist: scikit-learn (>=1.3.1,<2.0.0)
43
43
  Requires-Dist: sqlmodel (>=0.0.22,<0.0.23)
44
44
  Requires-Dist: streamlit (>=1.31.0,<2.0.0)
@@ -16,14 +16,15 @@ 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=WC30Nr16RGueTafA9i67OIB-6KDHZRryhiLPzebg9_I,6740
20
- prediction_market_agent_tooling/deploy/agent.py,sha256=1a1VPaCA77MhK9wQwX1MjEycareP_NYfsm73YFXwyxY,22222
19
+ prediction_market_agent_tooling/config.py,sha256=114f3V9abaok27p5jX3UVr5b5gRUiSxBIYn8Snid34I,6731
20
+ prediction_market_agent_tooling/deploy/agent.py,sha256=s3XVNeuJ9mtlfsRB1RWLWUR0q9fMoptZqu1u-I6oiws,22420
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
23
23
  prediction_market_agent_tooling/deploy/constants.py,sha256=M5ty8URipYMGe_G-RzxRydK3AFL6CyvmqCraJUrLBnE,82
24
24
  prediction_market_agent_tooling/deploy/gcp/deploy.py,sha256=CYUgnfy-9XVk04kkxA_5yp0GE9Mw5caYqlFUZQ2j3ks,3739
25
25
  prediction_market_agent_tooling/deploy/gcp/kubernetes_models.py,sha256=OsPboCFGiZKsvGyntGZHwdqPlLTthITkNF5rJFvGgU8,2582
26
26
  prediction_market_agent_tooling/deploy/gcp/utils.py,sha256=oyW0jgrUT2Tr49c7GlpcMsYNQjoCSOcWis3q-MmVAhU,6089
27
+ prediction_market_agent_tooling/deploy/trade_interval.py,sha256=Xk9j45alQ_vrasGvsNyuW70XHIQ7wfvjoxNR3F6HYCw,1155
27
28
  prediction_market_agent_tooling/gtypes.py,sha256=tqp03PyY0Yhievl4XELfwAn0xOoecaTvBZ1Co6b-A7o,2541
28
29
  prediction_market_agent_tooling/jobs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
29
30
  prediction_market_agent_tooling/jobs/jobs.py,sha256=I07yh0GJ-xhlvQaOUQB8xlSnihhcbU2c7DZ4ZND14c0,1246
@@ -85,16 +86,19 @@ prediction_market_agent_tooling/tools/langfuse_.py,sha256=jI_4ROxqo41CCnWGS1vN_A
85
86
  prediction_market_agent_tooling/tools/langfuse_client_utils.py,sha256=B0PhAQyviFnVbtOCYMxYmcCn66cu9nbqAOIAZcdgiRI,5771
86
87
  prediction_market_agent_tooling/tools/omen/reality_accuracy.py,sha256=M1SF7iSW1gVlQSTskdVFTn09uPLST23YeipVIWj54io,2236
87
88
  prediction_market_agent_tooling/tools/parallelism.py,sha256=6Gou0hbjtMZrYvxjTDFUDZuxmE2nqZVbb6hkg1hF82A,1022
88
- prediction_market_agent_tooling/tools/safe.py,sha256=h0xOO0eNtitClf0fPkn-0oTc6A_bflDTee98V_aiV-A,5195
89
+ prediction_market_agent_tooling/tools/relevant_news_analysis/data_models.py,sha256=95l84aztFaxcRLLcRQ46yKJbIlOEuDAbIGLouyliDzA,1316
90
+ prediction_market_agent_tooling/tools/relevant_news_analysis/relevant_news_analysis.py,sha256=OWLzwCbQS2b9hjwTRXTOjjplWXcGXFf3yjKEeK4kGbQ,5720
91
+ prediction_market_agent_tooling/tools/relevant_news_analysis/relevant_news_cache.py,sha256=2yxtBIDyMT_6CsTpZyuIv_2dy2B9WgEOaTT1fSloBu0,3223
92
+ prediction_market_agent_tooling/tools/safe.py,sha256=9vxGGLvSPnfy-sxUFDpBTe8omqpGXP7MzvGPp6bRxrU,5197
89
93
  prediction_market_agent_tooling/tools/singleton.py,sha256=CiIELUiI-OeS7U7eeHEt0rnVhtQGzwoUdAgn_7u_GBM,729
90
94
  prediction_market_agent_tooling/tools/streamlit_user_login.py,sha256=NXEqfjT9Lc9QtliwSGRASIz1opjQ7Btme43H4qJbzgE,3010
91
95
  prediction_market_agent_tooling/tools/tavily/tavily_models.py,sha256=Rz4tZzwCRzPaq49SFT33SCRQrqHXtqWdD9ajb2tGCWc,2723
92
- prediction_market_agent_tooling/tools/tavily/tavily_search.py,sha256=inGgWo_TFLA7Q0agYx2MYdEsh659oIdovQMniiG_Q20,4895
96
+ prediction_market_agent_tooling/tools/tavily/tavily_search.py,sha256=UPSp0S5Sql52X6UlU2Ki_iO-gmDJSMs5enn9AV_IZRM,4896
93
97
  prediction_market_agent_tooling/tools/tavily/tavily_storage.py,sha256=t-tZzbCzBBdFedRZDuVBn3A3mIDX8Z5wza6SxWswu_E,4093
94
98
  prediction_market_agent_tooling/tools/utils.py,sha256=W-9SqeCKd51BYMRhDjYPQ7lfNO_zE9EvYpmu2r5WXGA,7163
95
- prediction_market_agent_tooling/tools/web3_utils.py,sha256=dkcjG-LtuaWRh7WEMzRGmZ5B5rsxZTlliFOI6fj-EJ8,11842
96
- prediction_market_agent_tooling-0.55.0.dist-info/LICENSE,sha256=6or154nLLU6bELzjh0mCreFjt0m2v72zLi3yHE0QbeE,7650
97
- prediction_market_agent_tooling-0.55.0.dist-info/METADATA,sha256=2a-TbhiR5XyBGScQZDd1pV1vzC-LBWt7zFa6WorpmD8,8056
98
- prediction_market_agent_tooling-0.55.0.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
99
- prediction_market_agent_tooling-0.55.0.dist-info/entry_points.txt,sha256=m8PukHbeH5g0IAAmOf_1Ahm-sGAMdhSSRQmwtpmi2s8,81
100
- prediction_market_agent_tooling-0.55.0.dist-info/RECORD,,
99
+ prediction_market_agent_tooling/tools/web3_utils.py,sha256=44W8siSLNQxeib98bbwAe7V5C609NHNlUuxwuWIRDiY,11838
100
+ prediction_market_agent_tooling-0.55.1.dist-info/LICENSE,sha256=6or154nLLU6bELzjh0mCreFjt0m2v72zLi3yHE0QbeE,7650
101
+ prediction_market_agent_tooling-0.55.1.dist-info/METADATA,sha256=chzNuISP7K3sgt_Mj0fFX6bQu9JFkOXTvYgmqaLFcMU,8056
102
+ prediction_market_agent_tooling-0.55.1.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
103
+ prediction_market_agent_tooling-0.55.1.dist-info/entry_points.txt,sha256=m8PukHbeH5g0IAAmOf_1Ahm-sGAMdhSSRQmwtpmi2s8,81
104
+ prediction_market_agent_tooling-0.55.1.dist-info/RECORD,,