prediction-market-agent-tooling 0.42.1__py3-none-any.whl → 0.43.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.
- prediction_market_agent_tooling/markets/agent_market.py +1 -0
- prediction_market_agent_tooling/markets/manifold/manifold.py +5 -3
- prediction_market_agent_tooling/markets/metaculus/metaculus.py +3 -0
- prediction_market_agent_tooling/markets/omen/omen.py +3 -0
- prediction_market_agent_tooling/markets/polymarket/polymarket.py +1 -0
- prediction_market_agent_tooling/tools/is_predictable.py +88 -12
- prediction_market_agent_tooling/tools/parallelism.py +2 -0
- prediction_market_agent_tooling/tools/utils.py +4 -0
- {prediction_market_agent_tooling-0.42.1.dist-info → prediction_market_agent_tooling-0.43.1.dist-info}/METADATA +1 -1
- {prediction_market_agent_tooling-0.42.1.dist-info → prediction_market_agent_tooling-0.43.1.dist-info}/RECORD +13 -13
- {prediction_market_agent_tooling-0.42.1.dist-info → prediction_market_agent_tooling-0.43.1.dist-info}/LICENSE +0 -0
- {prediction_market_agent_tooling-0.42.1.dist-info → prediction_market_agent_tooling-0.43.1.dist-info}/WHEEL +0 -0
- {prediction_market_agent_tooling-0.42.1.dist-info → prediction_market_agent_tooling-0.43.1.dist-info}/entry_points.txt +0 -0
@@ -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
|
-
|
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:
|
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:
|
@@ -2,6 +2,7 @@ from loguru import logger
|
|
2
2
|
|
3
3
|
from prediction_market_agent_tooling.config import APIKeys
|
4
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
|
5
6
|
|
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.
|
7
8
|
QUESTION_IS_PREDICTABLE_BINARY_PROMPT = """Main signs about a fully qualified question (sometimes referred to as a "market"):
|
@@ -28,6 +29,47 @@ 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".
|
29
30
|
"""
|
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
|
+
|
31
73
|
|
32
74
|
@persistent_inmemory_cache
|
33
75
|
def is_predictable_binary(
|
@@ -42,12 +84,12 @@ def is_predictable_binary(
|
|
42
84
|
from langchain.prompts import ChatPromptTemplate
|
43
85
|
from langchain_openai import ChatOpenAI
|
44
86
|
except ImportError:
|
45
|
-
logger.
|
87
|
+
logger.error("langchain not installed, skipping is_predictable_binary")
|
46
88
|
return True
|
47
89
|
|
48
90
|
llm = ChatOpenAI(
|
49
91
|
model=engine,
|
50
|
-
temperature=
|
92
|
+
temperature=LLM_SUPER_LOW_TEMPERATURE,
|
51
93
|
api_key=APIKeys().openai_api_key_secretstr_v1,
|
52
94
|
)
|
53
95
|
|
@@ -55,20 +97,54 @@ def is_predictable_binary(
|
|
55
97
|
messages = prompt.format_messages(question=question)
|
56
98
|
completion = str(llm(messages, max_tokens=512).content)
|
57
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)
|
58
140
|
try:
|
59
141
|
decision = completion.lower().rsplit("decision", 1)[1]
|
60
142
|
except IndexError as e:
|
61
|
-
raise ValueError(
|
62
|
-
f"Invalid completion in is_predictable for `{question}`: {completion}"
|
63
|
-
) from e
|
143
|
+
raise ValueError(f"Invalid completion for `{question}`: {completion}") from e
|
64
144
|
|
65
145
|
if "yes" in decision:
|
66
|
-
|
146
|
+
return True
|
67
147
|
elif "no" in decision:
|
68
|
-
|
148
|
+
return False
|
69
149
|
else:
|
70
|
-
raise ValueError(
|
71
|
-
f"Invalid completion in is_predictable for `{question}`: {completion}"
|
72
|
-
)
|
73
|
-
|
74
|
-
return is_predictable
|
150
|
+
raise ValueError(f"Invalid completion for `{question}`: {completion}")
|
@@ -1,10 +1,12 @@
|
|
1
1
|
import concurrent
|
2
2
|
from concurrent.futures import Executor
|
3
|
+
from concurrent.futures.process import ProcessPoolExecutor
|
3
4
|
from concurrent.futures.thread import ThreadPoolExecutor
|
4
5
|
from typing import Callable, Generator, TypeVar
|
5
6
|
|
6
7
|
# Max workers to 5 to avoid rate limiting on some APIs, create a custom executor if you need more workers.
|
7
8
|
DEFAULT_THREADPOOL_EXECUTOR = ThreadPoolExecutor(max_workers=5)
|
9
|
+
DEFAULT_PROCESSPOOL_EXECUTOR = ProcessPoolExecutor(max_workers=5)
|
8
10
|
|
9
11
|
A = TypeVar("A")
|
10
12
|
B = TypeVar("B")
|
@@ -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],
|
@@ -21,28 +21,28 @@ prediction_market_agent_tooling/deploy/gcp/kubernetes_models.py,sha256=qYIHRxQLa
|
|
21
21
|
prediction_market_agent_tooling/deploy/gcp/utils.py,sha256=oyW0jgrUT2Tr49c7GlpcMsYNQjoCSOcWis3q-MmVAhU,6089
|
22
22
|
prediction_market_agent_tooling/gtypes.py,sha256=lbV2nsPyhMIRI9olx0_6A06jwTWKYBPGMxyiGVFysag,2467
|
23
23
|
prediction_market_agent_tooling/loggers.py,sha256=ua9rynYmsbOJZjxPIFxRBooomeN08zuLSJ7lxZMDS7w,3133
|
24
|
-
prediction_market_agent_tooling/markets/agent_market.py,sha256=
|
24
|
+
prediction_market_agent_tooling/markets/agent_market.py,sha256=4xMZSiNdr5NiJxuPWqhA6tnl4VloAxSpLvQdY7ySwAA,8393
|
25
25
|
prediction_market_agent_tooling/markets/categorize.py,sha256=HyKSFHXPL7Hfe90ahbF7xszamYREUVrPkLcpifw1V9Y,935
|
26
26
|
prediction_market_agent_tooling/markets/data_models.py,sha256=qD0LyFkzimaMkDVE0QO2a4I9fQ8qpO2qPmVzb-0JBik,2085
|
27
27
|
prediction_market_agent_tooling/markets/manifold/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
28
28
|
prediction_market_agent_tooling/markets/manifold/api.py,sha256=AC2zmkzpBU3P4kyybs7CgPbDg4hLAx3GY5mjgDi7qDo,7221
|
29
29
|
prediction_market_agent_tooling/markets/manifold/data_models.py,sha256=jHqOzOiN21wYvDNyh4VtbGtj4adWr6vA4liOQmh24cc,6239
|
30
|
-
prediction_market_agent_tooling/markets/manifold/manifold.py,sha256=
|
30
|
+
prediction_market_agent_tooling/markets/manifold/manifold.py,sha256=ai82Ozzx-BdtIDvORmepODh3S-EeyAvYBQyQUEarMLg,4179
|
31
31
|
prediction_market_agent_tooling/markets/manifold/utils.py,sha256=cPPFWXm3vCYH1jy7_ctJZuQH9ZDaPL4_AgAYzGWkoow,513
|
32
32
|
prediction_market_agent_tooling/markets/markets.py,sha256=Hz3E7LJ5HIjCHQtdU5_Bymav2dYT0dDxKOL0i8mV0mg,3142
|
33
33
|
prediction_market_agent_tooling/markets/metaculus/api.py,sha256=gvPQVAM5NlCyWzEMt4WML9saRBsK9eiHAZP6jwirVqc,2750
|
34
34
|
prediction_market_agent_tooling/markets/metaculus/data_models.py,sha256=6TBy17xntdLBR61QCE5wddwTa_k2D0D8ZgK6p7sGUuc,2448
|
35
|
-
prediction_market_agent_tooling/markets/metaculus/metaculus.py,sha256=
|
35
|
+
prediction_market_agent_tooling/markets/metaculus/metaculus.py,sha256=uNF7LP4evvubk818g2zbX1VlnFxeUQOkNgx_e_LwaJA,3416
|
36
36
|
prediction_market_agent_tooling/markets/omen/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
37
37
|
prediction_market_agent_tooling/markets/omen/data_models.py,sha256=oY-5wvFR4lXaTsmXVKrqrAQ8TWd-mAHLaxI1ETatLOc,14477
|
38
|
-
prediction_market_agent_tooling/markets/omen/omen.py,sha256=
|
38
|
+
prediction_market_agent_tooling/markets/omen/omen.py,sha256=GSuUP8gjFKy6zp2dfq5AGlzu5T7B08cFdjjlw07rSdU,39114
|
39
39
|
prediction_market_agent_tooling/markets/omen/omen_contracts.py,sha256=JGXCO9MIVr-DGyoH2sxReAw7ZDTC_ev0UxDpq1QBv5Q,21854
|
40
40
|
prediction_market_agent_tooling/markets/omen/omen_resolving.py,sha256=g77QsQ5WnSI2rzBlX87L_EhWMwobkyXyfRhHQmpAdzo,9012
|
41
41
|
prediction_market_agent_tooling/markets/omen/omen_subgraph_handler.py,sha256=kDbeZ8ImLtBSFz0GoGdCqeC1Xd3_eGMAxvmLFT8kp8Y,25222
|
42
42
|
prediction_market_agent_tooling/markets/polymarket/api.py,sha256=HXmA1akA0qDj0m3e-GEvWG8x75pm6BX4H7YJPQcST7I,4767
|
43
43
|
prediction_market_agent_tooling/markets/polymarket/data_models.py,sha256=9CJzakyEcsn6DQBK2nOXjOMzTZBLAmK_KqevXvW17DI,4292
|
44
44
|
prediction_market_agent_tooling/markets/polymarket/data_models_web.py,sha256=f8SRQy0Rn-gIHSEMrJJAI8H3J7l8lzOLj3aCMe0vJv8,11324
|
45
|
-
prediction_market_agent_tooling/markets/polymarket/polymarket.py,sha256=
|
45
|
+
prediction_market_agent_tooling/markets/polymarket/polymarket.py,sha256=xGJejGYoDbLBfXabhOI85ZMNnAMsWTedCCPKP6KfGno,2721
|
46
46
|
prediction_market_agent_tooling/markets/polymarket/utils.py,sha256=m4JG6WULh5epCJt4XBMHg0ae5NoVhqlOvAl0A7DR9iM,2023
|
47
47
|
prediction_market_agent_tooling/monitor/langfuse/langfuse_wrapper.py,sha256=b6T69YB1x8kSUvW9uRFuSWPLOrXzapZG7m5O5SU0QTQ,895
|
48
48
|
prediction_market_agent_tooling/monitor/markets/manifold.py,sha256=GdYpgRX1GahDi-75Mr53jgtEg6nWcs_rHDUkg4o_7dQ,3352
|
@@ -66,15 +66,15 @@ prediction_market_agent_tooling/tools/google.py,sha256=SfVDxb3oEOUK8mpd0l3mTX9yb
|
|
66
66
|
prediction_market_agent_tooling/tools/hexbytes_custom.py,sha256=Bp94qgPjvjWf1Vb4lNzGFDXRdThw1rJ91vL6r2PWq5E,2096
|
67
67
|
prediction_market_agent_tooling/tools/image_gen/image_gen.py,sha256=HzRwBx62hOXBOmrtpkXaP9Qq1Ku03uUGdREocyjLQ_k,1266
|
68
68
|
prediction_market_agent_tooling/tools/image_gen/market_thumbnail_gen.py,sha256=g-2BWS11CS7K6QRNbZRMTX_Xo2xOwjyCdhnwaQygX1Y,1104
|
69
|
-
prediction_market_agent_tooling/tools/is_predictable.py,sha256=
|
70
|
-
prediction_market_agent_tooling/tools/parallelism.py,sha256=
|
69
|
+
prediction_market_agent_tooling/tools/is_predictable.py,sha256=EobE2J0g2mfwD-o3Jv-cK6_EVMlnItZQunqWiNLqOvI,6188
|
70
|
+
prediction_market_agent_tooling/tools/parallelism.py,sha256=Rz8QdVUWX8KCbr8UZfaC_b1GBWIb3bXwITUumuvBJ60,1633
|
71
71
|
prediction_market_agent_tooling/tools/safe.py,sha256=h0xOO0eNtitClf0fPkn-0oTc6A_bflDTee98V_aiV-A,5195
|
72
72
|
prediction_market_agent_tooling/tools/singleton.py,sha256=CiIELUiI-OeS7U7eeHEt0rnVhtQGzwoUdAgn_7u_GBM,729
|
73
73
|
prediction_market_agent_tooling/tools/streamlit_user_login.py,sha256=NXEqfjT9Lc9QtliwSGRASIz1opjQ7Btme43H4qJbzgE,3010
|
74
|
-
prediction_market_agent_tooling/tools/utils.py,sha256
|
74
|
+
prediction_market_agent_tooling/tools/utils.py,sha256=JE9YWtPPhnTgLiOyGAZDNG5K8nCwUY9IZEuAlm9UcxA,6611
|
75
75
|
prediction_market_agent_tooling/tools/web3_utils.py,sha256=nKRHmdLnWSKd3wpo-cysXGvhhrJ2Yf69sN2FFQfSt6s,10578
|
76
|
-
prediction_market_agent_tooling-0.
|
77
|
-
prediction_market_agent_tooling-0.
|
78
|
-
prediction_market_agent_tooling-0.
|
79
|
-
prediction_market_agent_tooling-0.
|
80
|
-
prediction_market_agent_tooling-0.
|
76
|
+
prediction_market_agent_tooling-0.43.1.dist-info/LICENSE,sha256=6or154nLLU6bELzjh0mCreFjt0m2v72zLi3yHE0QbeE,7650
|
77
|
+
prediction_market_agent_tooling-0.43.1.dist-info/METADATA,sha256=a-sGAV5KiQixdLUfQXr4NHxJ848IBQ2uzLsKTqNB-Xs,7634
|
78
|
+
prediction_market_agent_tooling-0.43.1.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
79
|
+
prediction_market_agent_tooling-0.43.1.dist-info/entry_points.txt,sha256=m8PukHbeH5g0IAAmOf_1Ahm-sGAMdhSSRQmwtpmi2s8,81
|
80
|
+
prediction_market_agent_tooling-0.43.1.dist-info/RECORD,,
|
File without changes
|
File without changes
|