prediction-market-agent-tooling 0.42.0__tar.gz → 0.43.0__tar.gz

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.
Files changed (80) hide show
  1. {prediction_market_agent_tooling-0.42.0 → prediction_market_agent_tooling-0.43.0}/PKG-INFO +3 -3
  2. {prediction_market_agent_tooling-0.42.0 → prediction_market_agent_tooling-0.43.0}/prediction_market_agent_tooling/config.py +10 -1
  3. {prediction_market_agent_tooling-0.42.0 → prediction_market_agent_tooling-0.43.0}/prediction_market_agent_tooling/markets/agent_market.py +1 -0
  4. {prediction_market_agent_tooling-0.42.0 → prediction_market_agent_tooling-0.43.0}/prediction_market_agent_tooling/markets/categorize.py +1 -1
  5. {prediction_market_agent_tooling-0.42.0 → prediction_market_agent_tooling-0.43.0}/prediction_market_agent_tooling/markets/manifold/manifold.py +5 -3
  6. {prediction_market_agent_tooling-0.42.0 → prediction_market_agent_tooling-0.43.0}/prediction_market_agent_tooling/markets/metaculus/metaculus.py +3 -0
  7. {prediction_market_agent_tooling-0.42.0 → prediction_market_agent_tooling-0.43.0}/prediction_market_agent_tooling/markets/omen/omen.py +3 -0
  8. {prediction_market_agent_tooling-0.42.0 → prediction_market_agent_tooling-0.43.0}/prediction_market_agent_tooling/markets/polymarket/polymarket.py +1 -0
  9. {prediction_market_agent_tooling-0.42.0 → prediction_market_agent_tooling-0.43.0}/prediction_market_agent_tooling/tools/image_gen/market_thumbnail_gen.py +1 -1
  10. prediction_market_agent_tooling-0.43.0/prediction_market_agent_tooling/tools/is_predictable.py +150 -0
  11. {prediction_market_agent_tooling-0.42.0 → prediction_market_agent_tooling-0.43.0}/prediction_market_agent_tooling/tools/utils.py +4 -0
  12. {prediction_market_agent_tooling-0.42.0 → prediction_market_agent_tooling-0.43.0}/pyproject.toml +3 -3
  13. prediction_market_agent_tooling-0.42.0/prediction_market_agent_tooling/tools/is_predictable.py +0 -74
  14. {prediction_market_agent_tooling-0.42.0 → prediction_market_agent_tooling-0.43.0}/LICENSE +0 -0
  15. {prediction_market_agent_tooling-0.42.0 → prediction_market_agent_tooling-0.43.0}/README.md +0 -0
  16. {prediction_market_agent_tooling-0.42.0 → prediction_market_agent_tooling-0.43.0}/prediction_market_agent_tooling/abis/erc20.abi.json +0 -0
  17. {prediction_market_agent_tooling-0.42.0 → prediction_market_agent_tooling-0.43.0}/prediction_market_agent_tooling/abis/omen_dxdao.abi.json +0 -0
  18. {prediction_market_agent_tooling-0.42.0 → prediction_market_agent_tooling-0.43.0}/prediction_market_agent_tooling/abis/omen_fpmm.abi.json +0 -0
  19. {prediction_market_agent_tooling-0.42.0 → prediction_market_agent_tooling-0.43.0}/prediction_market_agent_tooling/abis/omen_fpmm_conditionaltokens.abi.json +0 -0
  20. {prediction_market_agent_tooling-0.42.0 → prediction_market_agent_tooling-0.43.0}/prediction_market_agent_tooling/abis/omen_fpmm_factory.abi.json +0 -0
  21. {prediction_market_agent_tooling-0.42.0 → prediction_market_agent_tooling-0.43.0}/prediction_market_agent_tooling/abis/omen_kleros.abi.json +0 -0
  22. {prediction_market_agent_tooling-0.42.0 → prediction_market_agent_tooling-0.43.0}/prediction_market_agent_tooling/abis/omen_oracle.abi.json +0 -0
  23. {prediction_market_agent_tooling-0.42.0 → prediction_market_agent_tooling-0.43.0}/prediction_market_agent_tooling/abis/omen_realitio.abi.json +0 -0
  24. {prediction_market_agent_tooling-0.42.0 → prediction_market_agent_tooling-0.43.0}/prediction_market_agent_tooling/abis/omen_thumbnailmapping.abi.json +0 -0
  25. {prediction_market_agent_tooling-0.42.0 → prediction_market_agent_tooling-0.43.0}/prediction_market_agent_tooling/abis/wxdai.abi.json +0 -0
  26. {prediction_market_agent_tooling-0.42.0 → prediction_market_agent_tooling-0.43.0}/prediction_market_agent_tooling/benchmark/__init__.py +0 -0
  27. {prediction_market_agent_tooling-0.42.0 → prediction_market_agent_tooling-0.43.0}/prediction_market_agent_tooling/benchmark/agents.py +0 -0
  28. {prediction_market_agent_tooling-0.42.0 → prediction_market_agent_tooling-0.43.0}/prediction_market_agent_tooling/benchmark/benchmark.py +0 -0
  29. {prediction_market_agent_tooling-0.42.0 → prediction_market_agent_tooling-0.43.0}/prediction_market_agent_tooling/benchmark/utils.py +0 -0
  30. {prediction_market_agent_tooling-0.42.0 → prediction_market_agent_tooling-0.43.0}/prediction_market_agent_tooling/deploy/agent.py +0 -0
  31. {prediction_market_agent_tooling-0.42.0 → prediction_market_agent_tooling-0.43.0}/prediction_market_agent_tooling/deploy/agent_example.py +0 -0
  32. {prediction_market_agent_tooling-0.42.0 → prediction_market_agent_tooling-0.43.0}/prediction_market_agent_tooling/deploy/constants.py +0 -0
  33. {prediction_market_agent_tooling-0.42.0 → prediction_market_agent_tooling-0.43.0}/prediction_market_agent_tooling/deploy/gcp/deploy.py +0 -0
  34. {prediction_market_agent_tooling-0.42.0 → prediction_market_agent_tooling-0.43.0}/prediction_market_agent_tooling/deploy/gcp/kubernetes_models.py +0 -0
  35. {prediction_market_agent_tooling-0.42.0 → prediction_market_agent_tooling-0.43.0}/prediction_market_agent_tooling/deploy/gcp/utils.py +0 -0
  36. {prediction_market_agent_tooling-0.42.0 → prediction_market_agent_tooling-0.43.0}/prediction_market_agent_tooling/gtypes.py +0 -0
  37. {prediction_market_agent_tooling-0.42.0 → prediction_market_agent_tooling-0.43.0}/prediction_market_agent_tooling/loggers.py +0 -0
  38. {prediction_market_agent_tooling-0.42.0 → prediction_market_agent_tooling-0.43.0}/prediction_market_agent_tooling/markets/data_models.py +0 -0
  39. {prediction_market_agent_tooling-0.42.0 → prediction_market_agent_tooling-0.43.0}/prediction_market_agent_tooling/markets/manifold/__init__.py +0 -0
  40. {prediction_market_agent_tooling-0.42.0 → prediction_market_agent_tooling-0.43.0}/prediction_market_agent_tooling/markets/manifold/api.py +0 -0
  41. {prediction_market_agent_tooling-0.42.0 → prediction_market_agent_tooling-0.43.0}/prediction_market_agent_tooling/markets/manifold/data_models.py +0 -0
  42. {prediction_market_agent_tooling-0.42.0 → prediction_market_agent_tooling-0.43.0}/prediction_market_agent_tooling/markets/manifold/utils.py +0 -0
  43. {prediction_market_agent_tooling-0.42.0 → prediction_market_agent_tooling-0.43.0}/prediction_market_agent_tooling/markets/markets.py +0 -0
  44. {prediction_market_agent_tooling-0.42.0 → prediction_market_agent_tooling-0.43.0}/prediction_market_agent_tooling/markets/metaculus/api.py +0 -0
  45. {prediction_market_agent_tooling-0.42.0 → prediction_market_agent_tooling-0.43.0}/prediction_market_agent_tooling/markets/metaculus/data_models.py +0 -0
  46. {prediction_market_agent_tooling-0.42.0 → prediction_market_agent_tooling-0.43.0}/prediction_market_agent_tooling/markets/omen/__init__.py +0 -0
  47. {prediction_market_agent_tooling-0.42.0 → prediction_market_agent_tooling-0.43.0}/prediction_market_agent_tooling/markets/omen/data_models.py +0 -0
  48. {prediction_market_agent_tooling-0.42.0 → prediction_market_agent_tooling-0.43.0}/prediction_market_agent_tooling/markets/omen/omen_contracts.py +0 -0
  49. {prediction_market_agent_tooling-0.42.0 → prediction_market_agent_tooling-0.43.0}/prediction_market_agent_tooling/markets/omen/omen_resolving.py +0 -0
  50. {prediction_market_agent_tooling-0.42.0 → prediction_market_agent_tooling-0.43.0}/prediction_market_agent_tooling/markets/omen/omen_subgraph_handler.py +0 -0
  51. {prediction_market_agent_tooling-0.42.0 → prediction_market_agent_tooling-0.43.0}/prediction_market_agent_tooling/markets/polymarket/api.py +0 -0
  52. {prediction_market_agent_tooling-0.42.0 → prediction_market_agent_tooling-0.43.0}/prediction_market_agent_tooling/markets/polymarket/data_models.py +0 -0
  53. {prediction_market_agent_tooling-0.42.0 → prediction_market_agent_tooling-0.43.0}/prediction_market_agent_tooling/markets/polymarket/data_models_web.py +0 -0
  54. {prediction_market_agent_tooling-0.42.0 → prediction_market_agent_tooling-0.43.0}/prediction_market_agent_tooling/markets/polymarket/utils.py +0 -0
  55. {prediction_market_agent_tooling-0.42.0 → prediction_market_agent_tooling-0.43.0}/prediction_market_agent_tooling/monitor/langfuse/langfuse_wrapper.py +0 -0
  56. {prediction_market_agent_tooling-0.42.0 → prediction_market_agent_tooling-0.43.0}/prediction_market_agent_tooling/monitor/markets/manifold.py +0 -0
  57. {prediction_market_agent_tooling-0.42.0 → prediction_market_agent_tooling-0.43.0}/prediction_market_agent_tooling/monitor/markets/metaculus.py +0 -0
  58. {prediction_market_agent_tooling-0.42.0 → prediction_market_agent_tooling-0.43.0}/prediction_market_agent_tooling/monitor/markets/omen.py +0 -0
  59. {prediction_market_agent_tooling-0.42.0 → prediction_market_agent_tooling-0.43.0}/prediction_market_agent_tooling/monitor/markets/polymarket.py +0 -0
  60. {prediction_market_agent_tooling-0.42.0 → prediction_market_agent_tooling-0.43.0}/prediction_market_agent_tooling/monitor/monitor.py +0 -0
  61. {prediction_market_agent_tooling-0.42.0 → prediction_market_agent_tooling-0.43.0}/prediction_market_agent_tooling/monitor/monitor_app.py +0 -0
  62. {prediction_market_agent_tooling-0.42.0 → prediction_market_agent_tooling-0.43.0}/prediction_market_agent_tooling/monitor/monitor_settings.py +0 -0
  63. {prediction_market_agent_tooling-0.42.0 → prediction_market_agent_tooling-0.43.0}/prediction_market_agent_tooling/py.typed +0 -0
  64. {prediction_market_agent_tooling-0.42.0 → prediction_market_agent_tooling-0.43.0}/prediction_market_agent_tooling/tools/balances.py +0 -0
  65. {prediction_market_agent_tooling-0.42.0 → prediction_market_agent_tooling-0.43.0}/prediction_market_agent_tooling/tools/betting_strategies/kelly_criterion.py +0 -0
  66. {prediction_market_agent_tooling-0.42.0 → prediction_market_agent_tooling-0.43.0}/prediction_market_agent_tooling/tools/betting_strategies/market_moving.py +0 -0
  67. {prediction_market_agent_tooling-0.42.0 → prediction_market_agent_tooling-0.43.0}/prediction_market_agent_tooling/tools/betting_strategies/minimum_bet_to_win.py +0 -0
  68. {prediction_market_agent_tooling-0.42.0 → prediction_market_agent_tooling-0.43.0}/prediction_market_agent_tooling/tools/betting_strategies/stretch_bet_between.py +0 -0
  69. {prediction_market_agent_tooling-0.42.0 → prediction_market_agent_tooling-0.43.0}/prediction_market_agent_tooling/tools/cache.py +0 -0
  70. {prediction_market_agent_tooling-0.42.0 → prediction_market_agent_tooling-0.43.0}/prediction_market_agent_tooling/tools/contract.py +0 -0
  71. {prediction_market_agent_tooling-0.42.0 → prediction_market_agent_tooling-0.43.0}/prediction_market_agent_tooling/tools/costs.py +0 -0
  72. {prediction_market_agent_tooling-0.42.0 → prediction_market_agent_tooling-0.43.0}/prediction_market_agent_tooling/tools/gnosis_rpc.py +0 -0
  73. {prediction_market_agent_tooling-0.42.0 → prediction_market_agent_tooling-0.43.0}/prediction_market_agent_tooling/tools/google.py +0 -0
  74. {prediction_market_agent_tooling-0.42.0 → prediction_market_agent_tooling-0.43.0}/prediction_market_agent_tooling/tools/hexbytes_custom.py +0 -0
  75. {prediction_market_agent_tooling-0.42.0 → prediction_market_agent_tooling-0.43.0}/prediction_market_agent_tooling/tools/image_gen/image_gen.py +0 -0
  76. {prediction_market_agent_tooling-0.42.0 → prediction_market_agent_tooling-0.43.0}/prediction_market_agent_tooling/tools/parallelism.py +0 -0
  77. {prediction_market_agent_tooling-0.42.0 → prediction_market_agent_tooling-0.43.0}/prediction_market_agent_tooling/tools/safe.py +0 -0
  78. {prediction_market_agent_tooling-0.42.0 → prediction_market_agent_tooling-0.43.0}/prediction_market_agent_tooling/tools/singleton.py +0 -0
  79. {prediction_market_agent_tooling-0.42.0 → prediction_market_agent_tooling-0.43.0}/prediction_market_agent_tooling/tools/streamlit_user_login.py +0 -0
  80. {prediction_market_agent_tooling-0.42.0 → prediction_market_agent_tooling-0.43.0}/prediction_market_agent_tooling/tools/web3_utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: prediction-market-agent-tooling
3
- Version: 0.42.0
3
+ Version: 0.43.0
4
4
  Summary: Tools to benchmark, deploy and monitor prediction market agents.
5
5
  Author: Gnosis
6
6
  Requires-Python: >=3.10,<3.12
@@ -21,9 +21,9 @@ Requires-Dist: google-cloud-functions (>=1.16.0,<2.0.0)
21
21
  Requires-Dist: google-cloud-resource-manager (>=1.12.0,<2.0.0)
22
22
  Requires-Dist: google-cloud-secret-manager (>=2.18.2,<3.0.0)
23
23
  Requires-Dist: isort (>=5.13.2,<6.0.0)
24
- Requires-Dist: langchain (>=0.1.9,<0.2.0) ; extra == "langchain"
24
+ Requires-Dist: langchain (>=0.2.6,<0.3.0) ; extra == "langchain"
25
25
  Requires-Dist: langchain-community (>=0.0.19)
26
- Requires-Dist: langchain-openai (>=0.0.5,<0.0.6) ; extra == "langchain"
26
+ Requires-Dist: langchain-openai (>=0.1.0,<0.2.0) ; extra == "langchain"
27
27
  Requires-Dist: langfuse (>=2.27.1,<3.0.0)
28
28
  Requires-Dist: loguru (>=0.7.2,<0.8.0)
29
29
  Requires-Dist: numpy (>=1.26.4,<2.0.0)
@@ -3,9 +3,14 @@ import typing as t
3
3
  from gnosis.eth import EthereumClient
4
4
  from gnosis.safe import Safe
5
5
  from pydantic.types import SecretStr
6
+ from pydantic.v1.types import SecretStr as SecretStrV1
6
7
  from pydantic_settings import BaseSettings, SettingsConfigDict
7
8
 
8
- from prediction_market_agent_tooling.gtypes import ChecksumAddress, PrivateKey
9
+ from prediction_market_agent_tooling.gtypes import (
10
+ ChecksumAddress,
11
+ PrivateKey,
12
+ secretstr_to_v1_secretstr,
13
+ )
9
14
  from prediction_market_agent_tooling.markets.manifold.api import get_authenticated_user
10
15
  from prediction_market_agent_tooling.tools.utils import check_not_none
11
16
  from prediction_market_agent_tooling.tools.web3_utils import private_key_to_public_key
@@ -87,6 +92,10 @@ class APIKeys(BaseSettings):
87
92
  self.OPENAI_API_KEY, "OPENAI_API_KEY missing in the environment."
88
93
  )
89
94
 
95
+ @property
96
+ def openai_api_key_secretstr_v1(self) -> SecretStrV1:
97
+ return secretstr_to_v1_secretstr(self.openai_api_key)
98
+
90
99
  @property
91
100
  def graph_api_key(self) -> SecretStr:
92
101
  return check_not_none(
@@ -47,6 +47,7 @@ class AgentMarket(BaseModel):
47
47
 
48
48
  id: str
49
49
  question: str
50
+ description: str | None
50
51
  outcomes: list[str]
51
52
  resolution: Resolution | None
52
53
  created_time: datetime | None
@@ -21,7 +21,7 @@ Write only the category itself, nothing else.
21
21
  prompt
22
22
  | ChatOpenAI(
23
23
  model=model,
24
- api_key=APIKeys().openai_api_key.get_secret_value(),
24
+ api_key=APIKeys().openai_api_key_secretstr_v1,
25
25
  )
26
26
  | StrOutputParser()
27
27
  )
@@ -13,11 +13,12 @@ from prediction_market_agent_tooling.markets.data_models import BetAmount, Curre
13
13
  from prediction_market_agent_tooling.markets.manifold.api import (
14
14
  get_authenticated_user,
15
15
  get_manifold_binary_markets,
16
+ get_manifold_market,
16
17
  place_bet,
17
18
  )
18
19
  from prediction_market_agent_tooling.markets.manifold.data_models import (
19
20
  MANIFOLD_BASE_URL,
20
- ManifoldMarket,
21
+ FullManifoldMarket,
21
22
  )
22
23
  from prediction_market_agent_tooling.tools.betting_strategies.minimum_bet_to_win import (
23
24
  minimum_bet_to_win,
@@ -58,10 +59,11 @@ class ManifoldAgentMarket(AgentMarket):
58
59
  )
59
60
 
60
61
  @staticmethod
61
- def from_data_model(model: ManifoldMarket) -> "ManifoldAgentMarket":
62
+ def from_data_model(model: FullManifoldMarket) -> "ManifoldAgentMarket":
62
63
  return ManifoldAgentMarket(
63
64
  id=model.id,
64
65
  question=model.question,
66
+ description=model.textDescription,
65
67
  outcomes=model.outcomes,
66
68
  resolution=model.resolution,
67
69
  created_time=model.createdTime,
@@ -100,7 +102,7 @@ class ManifoldAgentMarket(AgentMarket):
100
102
  raise ValueError(f"Unknown filter_by: {filter_by}")
101
103
 
102
104
  return [
103
- ManifoldAgentMarket.from_data_model(m)
105
+ ManifoldAgentMarket.from_data_model(get_manifold_market(m.id))
104
106
  for m in get_manifold_binary_markets(
105
107
  limit=limit,
106
108
  sort=sort,
@@ -25,6 +25,9 @@ class MetaculusAgentMarket(AgentMarket):
25
25
 
26
26
  have_predicted: bool
27
27
  base_url: t.ClassVar[str] = METACULUS_API_BASE_URL
28
+ description: str | None = (
29
+ None # Metaculus markets don't have a description, so just default to None.
30
+ )
28
31
 
29
32
  @staticmethod
30
33
  def from_data_model(model: MetaculusQuestion) -> "MetaculusAgentMarket":
@@ -91,6 +91,9 @@ class OmenAgentMarket(AgentMarket):
91
91
  )
92
92
 
93
93
  _binary_market_p_yes_history: list[Probability] | None = None
94
+ description: str | None = (
95
+ None # Omen markets don't have a description, so just default to None.
96
+ )
94
97
 
95
98
  @property
96
99
  def yes_index(self) -> int:
@@ -31,6 +31,7 @@ class PolymarketAgentMarket(AgentMarket):
31
31
  return PolymarketAgentMarket(
32
32
  id=model.id,
33
33
  question=model.question,
34
+ description=model.description,
34
35
  outcomes=[x.outcome for x in model.tokens],
35
36
  resolution=model.resolution,
36
37
  current_p_yes=model.p_yes,
@@ -14,7 +14,7 @@ def rewrite_question_into_image_generation_prompt(question: str) -> str:
14
14
  llm = ChatOpenAI(
15
15
  model="gpt-4-turbo",
16
16
  temperature=0.0,
17
- api_key=APIKeys().openai_api_key.get_secret_value(),
17
+ api_key=APIKeys().openai_api_key_secretstr_v1,
18
18
  )
19
19
  rewritten = str(
20
20
  llm.invoke(
@@ -0,0 +1,150 @@
1
+ from loguru import logger
2
+
3
+ from prediction_market_agent_tooling.config import APIKeys
4
+ from prediction_market_agent_tooling.tools.cache import persistent_inmemory_cache
5
+ from prediction_market_agent_tooling.tools.utils import LLM_SUPER_LOW_TEMPERATURE
6
+
7
+ # I tried to make it return a JSON, but it didn't work well in combo with asking it to do chain of thought.
8
+ QUESTION_IS_PREDICTABLE_BINARY_PROMPT = """Main signs about a fully qualified question (sometimes referred to as a "market"):
9
+ - The market's question needs to be specific, without use of pronouns.
10
+ - The market's question needs to have a clear future event.
11
+ - The market's question needs to have a clear time frame.
12
+ - The event in the market's question doesn't have to be ultra-specific, it will be decided by a crowd later on.
13
+ - If the market's question contains date, but without an year, it's okay.
14
+ - If the market's question contains year, but without an exact date, it's okay.
15
+ - The market's question can not be about itself or refer to itself.
16
+ - The answer is probably Google-able, after the event happened.
17
+ - The potential asnwer can be only "Yes" or "No".
18
+
19
+ Follow a chain of thought to evaluate if the question is fully qualified:
20
+
21
+ First, write the parts of the following question:
22
+
23
+ "{question}"
24
+
25
+ Then, write down what is the future event of the question, what it refers to and when that event will happen if the question contains it.
26
+
27
+ Then, explain why do you think it is or isn't fully qualified.
28
+
29
+ Finally, write your final decision, write `decision: ` followed by either "yes it is fully qualified" or "no it isn't fully qualified" about the question. Don't write anything else after that. You must include "yes" or "no".
30
+ """
31
+
32
+ QUESTION_IS_PREDICTABLE_WITHOUT_DESCRIPTION_PROMPT = """Main signs about a fully self-contained question (sometimes referred to as a "market"):
33
+ - Description of the question can not contain any additional information required to answer the question.
34
+
35
+ For the question:
36
+
37
+ ```
38
+ {question}
39
+ ```
40
+
41
+ And the description:
42
+
43
+ ```
44
+ {description}
45
+ ```
46
+
47
+ Description refers only to the text above and nothing else.
48
+
49
+ Even if the question is somewhat vague, but even the description does not contain enough of extra information, it's okay and the question is fully self-contained.
50
+ If the question is vague and the description contains the information required to answer the question, it's not fully self-contained and the answer is "no".
51
+
52
+ Follow a chain of thought to evaluate if the question doesn't need the description to be answered.
53
+
54
+ Start by examining detaily the question and the description. Write down their parts, what they refer to and what they contain.
55
+
56
+ Continue by writing comparison of the question and the description content. Write down what the question contains and what the description contains.
57
+
58
+ Explain, why do you think it does or doesn't need the description.
59
+
60
+ Description can contain additional information, but it can not contain any information required to answer the question.
61
+
62
+ Description can contain additional information about the exact resolution criteria, but the question should be answerable even without it.
63
+
64
+ As long as the question contains some time frame, it's okay if the description only specifies it in more detail.
65
+
66
+ Description usually contains the question in more detailed form, but the question on its own should be answerable.
67
+
68
+ For example, that means, description can not contain date if question doesn't contain it. Description can not contain target if the question doesn't contain it, etc.
69
+
70
+ Finally, write your final decision, write `decision: ` followed by either "yes it is fully self-contained" or "no it isn't fully self-contained" about the question. Don't write anything else after that. You must include "yes" or "no".
71
+ """
72
+
73
+
74
+ @persistent_inmemory_cache
75
+ def is_predictable_binary(
76
+ question: str,
77
+ engine: str = "gpt-4-1106-preview",
78
+ prompt_template: str = QUESTION_IS_PREDICTABLE_BINARY_PROMPT,
79
+ ) -> bool:
80
+ """
81
+ Evaluate if the question is actually answerable.
82
+ """
83
+ try:
84
+ from langchain.prompts import ChatPromptTemplate
85
+ from langchain_openai import ChatOpenAI
86
+ except ImportError:
87
+ logger.error("langchain not installed, skipping is_predictable_binary")
88
+ return True
89
+
90
+ llm = ChatOpenAI(
91
+ model=engine,
92
+ temperature=LLM_SUPER_LOW_TEMPERATURE,
93
+ api_key=APIKeys().openai_api_key_secretstr_v1,
94
+ )
95
+
96
+ prompt = ChatPromptTemplate.from_template(template=prompt_template)
97
+ messages = prompt.format_messages(question=question)
98
+ completion = str(llm(messages, max_tokens=512).content)
99
+
100
+ return parse_decision_yes_no_completion(question, completion)
101
+
102
+
103
+ @persistent_inmemory_cache
104
+ def is_predictable_without_description(
105
+ question: str,
106
+ description: str,
107
+ engine: str = "gpt-4-1106-preview",
108
+ prompt_template: str = QUESTION_IS_PREDICTABLE_WITHOUT_DESCRIPTION_PROMPT,
109
+ ) -> bool:
110
+ """
111
+ Evaluate if the question is fully self-contained.
112
+ """
113
+ try:
114
+ from langchain.prompts import ChatPromptTemplate
115
+ from langchain_openai import ChatOpenAI
116
+ except ImportError:
117
+ logger.error(
118
+ "langchain not installed, skipping is_predictable_without_description"
119
+ )
120
+ return True
121
+
122
+ llm = ChatOpenAI(
123
+ model=engine,
124
+ temperature=LLM_SUPER_LOW_TEMPERATURE,
125
+ api_key=APIKeys().openai_api_key_secretstr_v1,
126
+ )
127
+
128
+ prompt = ChatPromptTemplate.from_template(template=prompt_template)
129
+ messages = prompt.format_messages(
130
+ question=question,
131
+ description=description,
132
+ )
133
+ completion = str(llm(messages, max_tokens=512).content)
134
+
135
+ return parse_decision_yes_no_completion(question, completion)
136
+
137
+
138
+ def parse_decision_yes_no_completion(question: str, completion: str) -> bool:
139
+ logger.debug(completion)
140
+ try:
141
+ decision = completion.lower().rsplit("decision", 1)[1]
142
+ except IndexError as e:
143
+ raise ValueError(f"Invalid completion for `{question}`: {completion}") from e
144
+
145
+ if "yes" in decision:
146
+ return True
147
+ elif "no" in decision:
148
+ return False
149
+ else:
150
+ raise ValueError(f"Invalid completion for `{question}`: {completion}")
@@ -19,6 +19,10 @@ from prediction_market_agent_tooling.loggers import logger
19
19
 
20
20
  T = TypeVar("T")
21
21
 
22
+ # t=0 is mathematically impossible and it's not clear how OpenAI (and others) handle it, as a result, even with t=0, gpt-4-turbo produces very different outputs,
23
+ # it seems that using a very low temperature is the best way to have as consistent outputs as possible: https://community.openai.com/t/why-the-api-output-is-inconsistent-even-after-the-temperature-is-set-to-0/329541/12
24
+ LLM_SUPER_LOW_TEMPERATURE = 0.00000001
25
+
22
26
 
23
27
  def check_not_none(
24
28
  value: Optional[T],
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "prediction-market-agent-tooling"
3
- version = "0.42.0"
3
+ version = "0.43.0"
4
4
  description = "Tools to benchmark, deploy and monitor prediction market agents."
5
5
  authors = ["Gnosis"]
6
6
  readme = "README.md"
@@ -31,8 +31,8 @@ scikit-learn = "^1.3.1"
31
31
  tabulate = "^0.9.0"
32
32
  types-pytz = "^2024.1.0.20240203"
33
33
  google-cloud-secret-manager = "^2.18.2"
34
- langchain = { version = "^0.1.9", optional = true}
35
- langchain-openai = { version = "^0.0.5", optional = true}
34
+ langchain = { version = "^0.2.6", optional = true}
35
+ langchain-openai = { version = "^0.1.0", optional = true}
36
36
  google-api-python-client = { version = "2.95.0", optional = true}
37
37
  subgrounds = "^1.9.1"
38
38
  loguru = "^0.7.2"
@@ -1,74 +0,0 @@
1
- from loguru import logger
2
-
3
- from prediction_market_agent_tooling.config import APIKeys
4
- from prediction_market_agent_tooling.tools.cache import persistent_inmemory_cache
5
-
6
- # I tried to make it return a JSON, but it didn't work well in combo with asking it to do chain of thought.
7
- QUESTION_IS_PREDICTABLE_BINARY_PROMPT = """Main signs about a fully qualified question (sometimes referred to as a "market"):
8
- - The market's question needs to be specific, without use of pronouns.
9
- - The market's question needs to have a clear future event.
10
- - The market's question needs to have a clear time frame.
11
- - The event in the market's question doesn't have to be ultra-specific, it will be decided by a crowd later on.
12
- - If the market's question contains date, but without an year, it's okay.
13
- - If the market's question contains year, but without an exact date, it's okay.
14
- - The market's question can not be about itself or refer to itself.
15
- - The answer is probably Google-able, after the event happened.
16
- - The potential asnwer can be only "Yes" or "No".
17
-
18
- Follow a chain of thought to evaluate if the question is fully qualified:
19
-
20
- First, write the parts of the following question:
21
-
22
- "{question}"
23
-
24
- Then, write down what is the future event of the question, what it refers to and when that event will happen if the question contains it.
25
-
26
- Then, explain why do you think it is or isn't fully qualified.
27
-
28
- Finally, write your final decision, write `decision: ` followed by either "yes it is fully qualified" or "no it isn't fully qualified" about the question. Don't write anything else after that. You must include "yes" or "no".
29
- """
30
-
31
-
32
- @persistent_inmemory_cache
33
- def is_predictable_binary(
34
- question: str,
35
- engine: str = "gpt-4-1106-preview",
36
- prompt_template: str = QUESTION_IS_PREDICTABLE_BINARY_PROMPT,
37
- ) -> bool:
38
- """
39
- Evaluate if the question is actually answerable.
40
- """
41
- try:
42
- from langchain.prompts import ChatPromptTemplate
43
- from langchain_openai import ChatOpenAI
44
- except ImportError:
45
- logger.info("langchain not installed, skipping is_predictable_binary")
46
- return True
47
-
48
- llm = ChatOpenAI(
49
- model=engine,
50
- temperature=0.0,
51
- api_key=APIKeys().openai_api_key.get_secret_value(),
52
- )
53
-
54
- prompt = ChatPromptTemplate.from_template(template=prompt_template)
55
- messages = prompt.format_messages(question=question)
56
- completion = str(llm(messages, max_tokens=512).content)
57
-
58
- try:
59
- decision = completion.lower().rsplit("decision", 1)[1]
60
- except IndexError as e:
61
- raise ValueError(
62
- f"Invalid completion in is_predictable for `{question}`: {completion}"
63
- ) from e
64
-
65
- if "yes" in decision:
66
- is_predictable = True
67
- elif "no" in decision:
68
- is_predictable = False
69
- else:
70
- raise ValueError(
71
- f"Invalid completion in is_predictable for `{question}`: {completion}"
72
- )
73
-
74
- return is_predictable