prediction-market-agent-tooling 0.65.4__py3-none-any.whl → 0.65.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.
@@ -65,6 +65,8 @@ class APIKeys(BaseSettings):
65
65
 
66
66
  SQLALCHEMY_DB_URL: t.Optional[SecretStr] = None
67
67
 
68
+ PERPLEXITY_API_KEY: t.Optional[SecretStr] = None
69
+
68
70
  ENABLE_CACHE: bool = False
69
71
  CACHE_DIR: str = "./.cache"
70
72
 
@@ -259,6 +261,12 @@ class APIKeys(BaseSettings):
259
261
  if self.model_fields[k].annotation not in SECRET_TYPES and v is not None
260
262
  }
261
263
 
264
+ @property
265
+ def perplexity_api_key(self) -> SecretStr:
266
+ return check_not_none(
267
+ self.PERPLEXITY_API_KEY, "PERPLEXITY_API_KEY missing in the environment."
268
+ )
269
+
262
270
  def model_dump_secrets(self) -> dict[str, t.Any]:
263
271
  return {
264
272
  k: v.get_secret_value() if isinstance(v, SecretStr) else v
@@ -222,6 +222,7 @@ class DeployablePredictionAgent(DeployableAgent):
222
222
  self.have_bet_on_market_since = observe()(self.have_bet_on_market_since) # type: ignore[method-assign]
223
223
  self.verify_market = observe()(self.verify_market) # type: ignore[method-assign]
224
224
  self.answer_binary_market = observe()(self.answer_binary_market) # type: ignore[method-assign]
225
+ self.answer_categorical_market = observe()(self.answer_categorical_market) # type: ignore[method-assign]
225
226
  self.process_market = observe()(self.process_market) # type: ignore[method-assign]
226
227
 
227
228
  def update_langfuse_trace_by_market(
@@ -321,7 +322,7 @@ class DeployablePredictionAgent(DeployableAgent):
321
322
  def fetch_categorical_markets(self) -> bool:
322
323
  # Check if the subclass has implemented the answer_categorical_market method, if yes, fetch categorical markets as well.
323
324
  if (
324
- self.answer_categorical_market.__func__ # type: ignore[attr-defined] # This works just fine, but mypy doesn't know about it for some reason.
325
+ self.answer_categorical_market.__wrapped__.__func__ # type: ignore[attr-defined] # This works just fine, but mypy doesn't know about it for some reason.
325
326
  is not DeployablePredictionAgent.answer_categorical_market
326
327
  ):
327
328
  return True
@@ -61,7 +61,8 @@ class LogprobsParser:
61
61
  (
62
62
  i
63
63
  for i in range(result_start_index, len(logprobs))
64
- if logprobs[i]["token"] in {",", '"', ",\n", "\",\n'", '",\n'}
64
+ if logprobs[i]["token"]
65
+ in {",", '"', ",\n", "\",\n'", '",\n', '"\n', "\n"}
65
66
  ),
66
67
  len(logprobs) - 1,
67
68
  )
@@ -0,0 +1,86 @@
1
+ from typing import Any, Dict, List, Optional
2
+
3
+ import httpx
4
+ from pydantic import SecretStr
5
+
6
+ from prediction_market_agent_tooling.tools.perplexity.perplexity_models import (
7
+ PerplexityModelSettings,
8
+ PerplexityRequestParameters,
9
+ PerplexityResponse,
10
+ )
11
+
12
+
13
+ class PerplexityModel:
14
+ def __init__(
15
+ self,
16
+ model_name: str,
17
+ *,
18
+ api_key: SecretStr,
19
+ completition_endpoint: str = "https://api.perplexity.ai/chat/completions",
20
+ ) -> None:
21
+ self.model_name = model_name
22
+ self.api_key = api_key
23
+ self.completition_endpoint = completition_endpoint
24
+
25
+ async def request(
26
+ self,
27
+ messages: List[dict[str, str]],
28
+ model_settings: Optional[PerplexityModelSettings],
29
+ model_request_parameters: PerplexityRequestParameters,
30
+ ) -> PerplexityResponse:
31
+ payload: Dict[str, Any] = {"model": self.model_name, "messages": messages}
32
+
33
+ if model_settings:
34
+ model_settings_dict = model_settings.model_dump()
35
+ model_settings_dict = {
36
+ k: v for k, v in model_settings_dict.items() if v is not None
37
+ }
38
+ payload.update(model_settings_dict)
39
+
40
+ params_dict = model_request_parameters.model_dump()
41
+ params_dict = {k: v for k, v in params_dict.items() if v is not None}
42
+
43
+ # Extract and handle search_context_size specially
44
+ if "search_context_size" in params_dict:
45
+ search_context_size = params_dict.pop("search_context_size")
46
+ payload["web_search_options"] = {"search_context_size": search_context_size}
47
+
48
+ # Add remaining Perplexity parameters to payload
49
+ payload.update(params_dict)
50
+
51
+ try:
52
+ async with httpx.AsyncClient(timeout=180) as client:
53
+ response = await client.post(
54
+ self.completition_endpoint,
55
+ headers={
56
+ "Authorization": f"Bearer {self.api_key.get_secret_value()}",
57
+ "Content-Type": "application/json",
58
+ },
59
+ json=payload,
60
+ )
61
+ response.raise_for_status()
62
+ result: dict[str, Any] = response.json()
63
+
64
+ choices = result.get("choices", [])
65
+ if not choices:
66
+ raise ValueError("Invalid response: no choices")
67
+
68
+ content = choices[0].get("message", {}).get("content")
69
+ if not content:
70
+ raise ValueError("Invalid response: no content")
71
+
72
+ return PerplexityResponse(
73
+ content=content,
74
+ citations=result.get("citations", []),
75
+ usage=result.get("usage", {}),
76
+ )
77
+ except httpx.HTTPStatusError as e:
78
+ raise ValueError(
79
+ f"HTTP error from Perplexity API: {e.response.status_code} - {e.response.text}"
80
+ ) from e
81
+ except httpx.RequestError as e:
82
+ raise ValueError(f"Request error to Perplexity API: {str(e)}") from e
83
+ except Exception as e:
84
+ raise ValueError(
85
+ f"Unexpected error in Perplexity API request: {str(e)}"
86
+ ) from e
@@ -0,0 +1,26 @@
1
+ from typing import Any, List, Literal, Optional
2
+
3
+ from pydantic import BaseModel
4
+
5
+
6
+ class PerplexityRequestParameters(BaseModel):
7
+ search_context_size: Optional[Literal["low", "medium", "high"]]
8
+ search_recency_filter: Optional[Literal["any", "day", "week", "month", "year"]]
9
+ search_return_related_questions: Optional[bool]
10
+ search_domain_filter: Optional[List[str]]
11
+ search_after_date_filter: Optional[str]
12
+ search_before_date_filter: Optional[str]
13
+
14
+
15
+ class PerplexityResponse(BaseModel):
16
+ content: str
17
+ citations: list[str]
18
+ usage: dict[str, Any]
19
+
20
+
21
+ class PerplexityModelSettings(BaseModel):
22
+ max_tokens: Optional[int] = None
23
+ temperature: Optional[float] = None
24
+ top_p: Optional[float] = None
25
+ frequency_penalty: Optional[float] = None
26
+ presence_penalty: Optional[float] = None
@@ -0,0 +1,73 @@
1
+ import asyncio
2
+ import typing as t
3
+ from datetime import date, timedelta
4
+
5
+ import tenacity
6
+
7
+ from prediction_market_agent_tooling.config import APIKeys
8
+ from prediction_market_agent_tooling.tools.caches.db_cache import db_cache
9
+ from prediction_market_agent_tooling.tools.perplexity.perplexity_client import (
10
+ PerplexityModel,
11
+ )
12
+ from prediction_market_agent_tooling.tools.perplexity.perplexity_models import (
13
+ PerplexityModelSettings,
14
+ PerplexityRequestParameters,
15
+ PerplexityResponse,
16
+ )
17
+
18
+ SYSTEM_PROMPT = "You are a helpful search assistant. Your task is to provide accurate information based on web searches."
19
+
20
+
21
+ @tenacity.retry(stop=tenacity.stop_after_attempt(3), wait=tenacity.wait_fixed(1))
22
+ @db_cache(
23
+ max_age=timedelta(days=1),
24
+ ignore_args=["api_keys"],
25
+ log_error_on_unsavable_data=False,
26
+ )
27
+ def perplexity_search(
28
+ query: str,
29
+ api_keys: APIKeys,
30
+ search_context_size: t.Literal["low", "medium", "high"] = "medium",
31
+ search_recency_filter: t.Literal["any", "day", "week", "month", "year"]
32
+ | None = None,
33
+ search_filter_before_date: date | None = None,
34
+ search_filter_after_date: date | None = None,
35
+ search_return_related_questions: bool | None = None,
36
+ include_domains: list[str] | None = None,
37
+ temperature: float = 0,
38
+ model_name: str = "sonar-pro",
39
+ max_tokens: int = 2048,
40
+ ) -> PerplexityResponse:
41
+ # Create messages in ModelMessage format
42
+ messages = [
43
+ {"role": "system", "content": SYSTEM_PROMPT},
44
+ {"role": "user", "content": query},
45
+ ]
46
+
47
+ # Define special parameters for the request and create the settings
48
+ model_settings = PerplexityModelSettings(
49
+ max_tokens=max_tokens, temperature=temperature
50
+ )
51
+
52
+ # Create a basic request parameters object with required base parameters
53
+ request_params = PerplexityRequestParameters(
54
+ search_domain_filter=include_domains,
55
+ search_after_date_filter=search_filter_after_date.strftime("%Y-%m-%d")
56
+ if search_filter_after_date
57
+ else None,
58
+ search_before_date_filter=search_filter_before_date.strftime("%Y-%m-%d")
59
+ if search_filter_before_date
60
+ else None,
61
+ search_recency_filter=search_recency_filter,
62
+ search_context_size=search_context_size,
63
+ search_return_related_questions=search_return_related_questions,
64
+ )
65
+
66
+ model = PerplexityModel(model_name=model_name, api_key=api_keys.perplexity_api_key)
67
+ return asyncio.run(
68
+ model.request(
69
+ messages=messages,
70
+ model_settings=model_settings,
71
+ model_request_parameters=request_params,
72
+ )
73
+ )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: prediction-market-agent-tooling
3
- Version: 0.65.4
3
+ Version: 0.65.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
@@ -23,8 +23,8 @@ prediction_market_agent_tooling/benchmark/agents.py,sha256=zC5tUM6pPTWtqSddOOSYV
23
23
  prediction_market_agent_tooling/benchmark/benchmark.py,sha256=KwMZzwise3sgmhdjw7xCgHMmjKHdHqQC-zc9untOLWg,17832
24
24
  prediction_market_agent_tooling/benchmark/utils.py,sha256=xQd7p9H08-OtN3iC4QT2i9bkUTmrXa6rxGXeg9yMhgU,2986
25
25
  prediction_market_agent_tooling/chains.py,sha256=1qQstoqXMwqwM7k-KH7MjMz8Ei-D83KZByvDbCZpAxs,116
26
- prediction_market_agent_tooling/config.py,sha256=UyhK6u261tBLVsRwvXJm9C0wy6UrUpfAKH6xk4CSfk8,11535
27
- prediction_market_agent_tooling/deploy/agent.py,sha256=kxfJNfuvGJ2LFReI-PCyjGuubZKIrPEYiyphaS6eKcM,25476
26
+ prediction_market_agent_tooling/config.py,sha256=-kJfdDr-m0R-tGZ1KRI-hJJk0mXDt142CAlvwaJ2N2I,11778
27
+ prediction_market_agent_tooling/deploy/agent.py,sha256=ddFvBUhB_WVWtuUGkiZNKBME4Hd3AdquVv588c1rpu0,25602
28
28
  prediction_market_agent_tooling/deploy/agent_example.py,sha256=yS1fWkHynr9MYGNOM2WsCnRWLPaffY4bOc6bIudrdd4,1377
29
29
  prediction_market_agent_tooling/deploy/betting_strategy.py,sha256=YYayGjTKW02d3BUavJ8M3NmFk41oldEM3FHbwppZGRM,17184
30
30
  prediction_market_agent_tooling/deploy/constants.py,sha256=Qe9cllgsGMkecfmbhXoFkPxuJyG6ATsrT87RF9SmPWM,249
@@ -37,7 +37,7 @@ prediction_market_agent_tooling/jobs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeu
37
37
  prediction_market_agent_tooling/jobs/jobs_models.py,sha256=DoZ9dlvVhpNrnINiR1uy6YUOsuzI_L-avBt362y5xXM,2467
38
38
  prediction_market_agent_tooling/jobs/omen/omen_jobs.py,sha256=qbTZ9HVvu_iP4dDxuvOZxAp6JsRKejvEW2YDYCnRmd4,5039
39
39
  prediction_market_agent_tooling/loggers.py,sha256=kFZ1BrI8hvWgZO1vzptFnYiOEDx9Ozs86DA9yF3bSgY,5212
40
- prediction_market_agent_tooling/logprobs_parser.py,sha256=Du1Yc-fAVSixQX_Zx6KWpgSzI_ZYhv5tS1b8IcOPPr8,4979
40
+ prediction_market_agent_tooling/logprobs_parser.py,sha256=DBlBQtWX8_URXhzTU3YWIPa76Zx3QDHlx1ARqbgJsVI,5008
41
41
  prediction_market_agent_tooling/markets/agent_market.py,sha256=smKuMaP1zyTtw31Robbj3ospF03xptWX0EDKPJbHH9I,19070
42
42
  prediction_market_agent_tooling/markets/base_subgraph_handler.py,sha256=7RaYO_4qAmQ6ZGM8oPK2-CkiJfKmV9MxM-rJlduaecU,1971
43
43
  prediction_market_agent_tooling/markets/blockchain_utils.py,sha256=gZMwCTO-1d2ALXeY7-LP6U4kCpotJ6GMPZwN11kFOfE,2604
@@ -100,6 +100,9 @@ prediction_market_agent_tooling/tools/langfuse_client_utils.py,sha256=6IvsqqNNfB
100
100
  prediction_market_agent_tooling/tools/omen/reality_accuracy.py,sha256=M1SF7iSW1gVlQSTskdVFTn09uPLST23YeipVIWj54io,2236
101
101
  prediction_market_agent_tooling/tools/omen/sell_positions.py,sha256=Q4oI7_QI3AkyxlH10VvxDahYVrphQa1Wnox2Ce_cf_k,2452
102
102
  prediction_market_agent_tooling/tools/parallelism.py,sha256=6Gou0hbjtMZrYvxjTDFUDZuxmE2nqZVbb6hkg1hF82A,1022
103
+ prediction_market_agent_tooling/tools/perplexity/perplexity_client.py,sha256=Oi5a_uaCAPtpTAEEVwD0SXWTsKkhCXOQjCBfa1eAuC0,3215
104
+ prediction_market_agent_tooling/tools/perplexity/perplexity_models.py,sha256=SfeR5FGQ2PqaxG4f4ij50LEnS9f2aeLplVwD7IZQh1s,820
105
+ prediction_market_agent_tooling/tools/perplexity/perplexity_search.py,sha256=Ii-5bqk6DygOCK1G78PDdz2sRTNvFYHVYVl2sajUbY4,2616
103
106
  prediction_market_agent_tooling/tools/relevant_news_analysis/data_models.py,sha256=95l84aztFaxcRLLcRQ46yKJbIlOEuDAbIGLouyliDzA,1316
104
107
  prediction_market_agent_tooling/tools/relevant_news_analysis/relevant_news_analysis.py,sha256=r4MdP5uEMlaCwoa2XQZzGq3oZEqnoo9S4dg8uzXfSOY,5473
105
108
  prediction_market_agent_tooling/tools/relevant_news_analysis/relevant_news_cache.py,sha256=kNWq92T11Knb9mYBZlMiZUzOpKgCd-5adanylQUMRJA,3085
@@ -116,8 +119,8 @@ prediction_market_agent_tooling/tools/tokens/usd.py,sha256=yuW8iPPtcpP4eLH2nORMD
116
119
  prediction_market_agent_tooling/tools/transaction_cache.py,sha256=K5YKNL2_tR10Iw2TD9fuP-CTGpBbZtNdgbd0B_R7pjg,1814
117
120
  prediction_market_agent_tooling/tools/utils.py,sha256=Jzpck3_QwShhejhgbAhmNxPSOPQJssBQep0eVemVjZ4,7064
118
121
  prediction_market_agent_tooling/tools/web3_utils.py,sha256=zRq-eeBGWt8uUGN9G_WfjmJ0eVvO8aWE9S0Pz_Y6AOA,12342
119
- prediction_market_agent_tooling-0.65.4.dist-info/LICENSE,sha256=6or154nLLU6bELzjh0mCreFjt0m2v72zLi3yHE0QbeE,7650
120
- prediction_market_agent_tooling-0.65.4.dist-info/METADATA,sha256=bG8oQxcVytt5TcAg1I-7qsmGqL2aCOZJ-FvKB-7tgQE,8734
121
- prediction_market_agent_tooling-0.65.4.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
122
- prediction_market_agent_tooling-0.65.4.dist-info/entry_points.txt,sha256=m8PukHbeH5g0IAAmOf_1Ahm-sGAMdhSSRQmwtpmi2s8,81
123
- prediction_market_agent_tooling-0.65.4.dist-info/RECORD,,
122
+ prediction_market_agent_tooling-0.65.6.dist-info/LICENSE,sha256=6or154nLLU6bELzjh0mCreFjt0m2v72zLi3yHE0QbeE,7650
123
+ prediction_market_agent_tooling-0.65.6.dist-info/METADATA,sha256=XT7Kp9vv8HBSZjedQV7VgRp7H4Awv4GQdjrzz1F7Z-E,8734
124
+ prediction_market_agent_tooling-0.65.6.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
125
+ prediction_market_agent_tooling-0.65.6.dist-info/entry_points.txt,sha256=m8PukHbeH5g0IAAmOf_1Ahm-sGAMdhSSRQmwtpmi2s8,81
126
+ prediction_market_agent_tooling-0.65.6.dist-info/RECORD,,