prediction-market-agent-tooling 0.32.0__py3-none-any.whl → 0.34.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.
- prediction_market_agent_tooling/markets/manifold/data_models.py +1 -1
- prediction_market_agent_tooling/monitor/monitor.py +36 -5
- prediction_market_agent_tooling/tools/streamlit_user_login.py +82 -0
- {prediction_market_agent_tooling-0.32.0.dist-info → prediction_market_agent_tooling-0.34.0.dist-info}/METADATA +2 -2
- {prediction_market_agent_tooling-0.32.0.dist-info → prediction_market_agent_tooling-0.34.0.dist-info}/RECORD +8 -7
- {prediction_market_agent_tooling-0.32.0.dist-info → prediction_market_agent_tooling-0.34.0.dist-info}/LICENSE +0 -0
- {prediction_market_agent_tooling-0.32.0.dist-info → prediction_market_agent_tooling-0.34.0.dist-info}/WHEEL +0 -0
- {prediction_market_agent_tooling-0.32.0.dist-info → prediction_market_agent_tooling-0.34.0.dist-info}/entry_points.txt +0 -0
@@ -79,7 +79,7 @@ class ManifoldMarket(BaseModel):
|
|
79
79
|
"""
|
80
80
|
Clip the timestamp to the maximum valid timestamp.
|
81
81
|
"""
|
82
|
-
max_timestamp = (datetime.max - timedelta(
|
82
|
+
max_timestamp = (datetime.max - timedelta(days=1)).timestamp()
|
83
83
|
value = int(min(value / 1000, max_timestamp))
|
84
84
|
return datetime.fromtimestamp(value)
|
85
85
|
|
@@ -185,7 +185,7 @@ def monitor_agent(agent: DeployedAgent) -> None:
|
|
185
185
|
col3.markdown(f"Public ID: `{agent.public_id}`")
|
186
186
|
|
187
187
|
show_agent_bets = st.checkbox(
|
188
|
-
"Show resolved bets", value=False, key=f"{agent.name}_show_bets"
|
188
|
+
"Show resolved bets statistics", value=False, key=f"{agent.name}_show_bets"
|
189
189
|
)
|
190
190
|
if not show_agent_bets:
|
191
191
|
return
|
@@ -203,16 +203,43 @@ def monitor_agent(agent: DeployedAgent) -> None:
|
|
203
203
|
"Is Correct": [bet.is_correct for bet in agent_bets],
|
204
204
|
"Profit": [round(bet.profit.amount, 2) for bet in agent_bets],
|
205
205
|
}
|
206
|
-
|
206
|
+
|
207
|
+
# Time column to use for x-axes and sorting
|
208
|
+
x_axis_column = st.selectbox(
|
209
|
+
"X-axis column",
|
210
|
+
["Created Time", "Resolved Time"],
|
211
|
+
key=f"{agent.name}_x_axis_column",
|
212
|
+
)
|
213
|
+
|
214
|
+
bets_df = pd.DataFrame(bets_info).sort_values(by=x_axis_column, ascending=False)
|
215
|
+
bets_df["x-axis-day"] = bets_df[x_axis_column].dt.date
|
207
216
|
|
208
217
|
# Metrics
|
209
218
|
col1, col2 = st.columns(2)
|
210
219
|
col1.metric(label="Number of bets", value=f"{len(agent_bets)}")
|
211
220
|
col2.metric(label="% Correct", value=f"{100 * bets_df['Is Correct'].mean():.2f}%")
|
212
221
|
|
222
|
+
# Chart of grouped accuracy per day
|
223
|
+
per_day_accuracy = bets_df.groupby("x-axis-day")["Is Correct"].mean()
|
224
|
+
per_day_accuracy_chart = (
|
225
|
+
alt.Chart(per_day_accuracy.reset_index())
|
226
|
+
.encode(
|
227
|
+
x=alt.X("x-axis-day", axis=alt.Axis(format="%Y-%m-%d"), title=None),
|
228
|
+
y=alt.Y("Is Correct", axis=alt.Axis(format=".2f")),
|
229
|
+
)
|
230
|
+
.interactive()
|
231
|
+
)
|
232
|
+
st.altair_chart(
|
233
|
+
per_day_accuracy_chart.mark_line()
|
234
|
+
+ per_day_accuracy_chart.transform_loess("x-axis-day", "Is Correct").mark_line(
|
235
|
+
color="red", strokeDash=[5, 5]
|
236
|
+
),
|
237
|
+
use_container_width=True,
|
238
|
+
)
|
239
|
+
|
213
240
|
# Chart of cumulative profit per day
|
214
241
|
profit_info = {
|
215
|
-
"Time": bets_df[
|
242
|
+
"Time": bets_df[x_axis_column],
|
216
243
|
"Cumulative Profit": bets_df["Profit"].astype(float),
|
217
244
|
}
|
218
245
|
profit_df = pd.DataFrame(profit_info)
|
@@ -233,8 +260,12 @@ def monitor_agent(agent: DeployedAgent) -> None:
|
|
233
260
|
)
|
234
261
|
|
235
262
|
# Table of resolved bets
|
236
|
-
st.
|
237
|
-
|
263
|
+
show_bet_history = st.checkbox(
|
264
|
+
"Show resolved bet history", value=False, key=f"{agent.name}_show_bet_history"
|
265
|
+
)
|
266
|
+
if show_bet_history:
|
267
|
+
st.subheader("Resolved Bet History")
|
268
|
+
st.table(bets_df.drop(columns=["x-axis-day"]))
|
238
269
|
|
239
270
|
|
240
271
|
def monitor_market(
|
@@ -0,0 +1,82 @@
|
|
1
|
+
from enum import Enum
|
2
|
+
|
3
|
+
import streamlit as st
|
4
|
+
from pydantic import BaseModel, SecretStr
|
5
|
+
from pydantic_settings import BaseSettings, SettingsConfigDict
|
6
|
+
|
7
|
+
from prediction_market_agent_tooling.loggers import logger
|
8
|
+
|
9
|
+
|
10
|
+
class LoggedInUser(BaseModel):
|
11
|
+
email: str
|
12
|
+
password: SecretStr
|
13
|
+
|
14
|
+
|
15
|
+
class LoginSettings(BaseSettings):
|
16
|
+
model_config = SettingsConfigDict(
|
17
|
+
env_file=".env", env_file_encoding="utf-8", extra="ignore"
|
18
|
+
)
|
19
|
+
free_for_everyone: bool = False
|
20
|
+
free_access_codes: list[SecretStr] = []
|
21
|
+
users: list[LoggedInUser] = []
|
22
|
+
|
23
|
+
|
24
|
+
class LoggedEnum(str, Enum):
|
25
|
+
SELF_PAYING = "self_paying"
|
26
|
+
FREE_ACCESS = "free_access"
|
27
|
+
USER_LOGGED_IN = "user_logged_in"
|
28
|
+
|
29
|
+
|
30
|
+
def find_logged_in_user(email: str, password: SecretStr) -> LoggedInUser | None:
|
31
|
+
login_settings = LoginSettings()
|
32
|
+
|
33
|
+
for user in login_settings.users:
|
34
|
+
if (
|
35
|
+
user.email == email
|
36
|
+
and user.password.get_secret_value() == password.get_secret_value()
|
37
|
+
):
|
38
|
+
return user
|
39
|
+
|
40
|
+
return None
|
41
|
+
|
42
|
+
|
43
|
+
def streamlit_login() -> tuple[LoggedEnum, LoggedInUser | None]:
|
44
|
+
login_settings = LoginSettings()
|
45
|
+
|
46
|
+
if login_settings.free_for_everyone:
|
47
|
+
logger.info("Free access for everyone!")
|
48
|
+
return LoggedEnum.FREE_ACCESS, None
|
49
|
+
|
50
|
+
if (
|
51
|
+
free_access_code := st.query_params.get("free_access_code")
|
52
|
+
) is not None and free_access_code in [
|
53
|
+
x.get_secret_value() for x in login_settings.free_access_codes
|
54
|
+
]:
|
55
|
+
logger.info(f"Using free access code: {free_access_code}.")
|
56
|
+
return LoggedEnum.FREE_ACCESS, None
|
57
|
+
|
58
|
+
# TODO: Because we are initializing APIKeys (based on environment variables) in random places in the code, the user can not provide their own access keys, such as OPENAI_API_KEY.
|
59
|
+
# Doing that would require to change the environment variables in the code, but Streamlit is using 1 thread per session, and the environment variables are shared between threads.
|
60
|
+
# So other users would get the secrets provided by the first user!
|
61
|
+
# Another option is to refactor the code, such that APIKeys are initialized in a single place, somewhere in the agent's initialisation and then, we can initialize them here based on the user's input and just provide them to the agent.
|
62
|
+
# After that's done, we should also have unique api keys per registered user.
|
63
|
+
self_paying = False
|
64
|
+
# self_paying = st.checkbox("I will provide my own access keys", value=False)
|
65
|
+
|
66
|
+
if not self_paying:
|
67
|
+
email = st.text_input("Email")
|
68
|
+
password = SecretStr(st.text_input("Password", type="password"))
|
69
|
+
logged_user = find_logged_in_user(email, password)
|
70
|
+
|
71
|
+
if logged_user is not None:
|
72
|
+
logger.info(f"Logged in as {email}.")
|
73
|
+
return LoggedEnum.USER_LOGGED_IN, logged_user
|
74
|
+
|
75
|
+
else:
|
76
|
+
st.error("Invalid email or password.")
|
77
|
+
st.stop()
|
78
|
+
|
79
|
+
else:
|
80
|
+
raise NotImplementedError(
|
81
|
+
"Should not happen. Self-paying is not implemented yet. See the comment above."
|
82
|
+
)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: prediction-market-agent-tooling
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.34.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
|
@@ -35,7 +35,7 @@ Requires-Dist: streamlit (>=1.31.0,<2.0.0)
|
|
35
35
|
Requires-Dist: subgrounds (>=1.8.1,<2.0.0)
|
36
36
|
Requires-Dist: tabulate (>=0.9.0,<0.10.0)
|
37
37
|
Requires-Dist: tqdm (>=4.66.2,<5.0.0)
|
38
|
-
Requires-Dist: typer (>=0.
|
38
|
+
Requires-Dist: typer (>=0.12.3,<0.13.0)
|
39
39
|
Requires-Dist: types-pytz (>=2024.1.0.20240203,<2025.0.0.0)
|
40
40
|
Requires-Dist: types-requests (>=2.31.0.0,<3.0.0.0)
|
41
41
|
Requires-Dist: web3 (>=6.15.1,<7.0.0)
|
@@ -25,7 +25,7 @@ prediction_market_agent_tooling/markets/categorize.py,sha256=yTd-lDMPW4ESDSzmxeL
|
|
25
25
|
prediction_market_agent_tooling/markets/data_models.py,sha256=uODY3aoFp8YYeLAUcrzMk1yU8pIKsTLobB9xIEGTmKs,1170
|
26
26
|
prediction_market_agent_tooling/markets/manifold/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
27
27
|
prediction_market_agent_tooling/markets/manifold/api.py,sha256=m6qOzDiyQfxj62Eo_SzzQLkX4ijpi8KtQKGd4CpKAsk,7307
|
28
|
-
prediction_market_agent_tooling/markets/manifold/data_models.py,sha256=
|
28
|
+
prediction_market_agent_tooling/markets/manifold/data_models.py,sha256=Iw-ajDPYhtfcTfN45nJN_kZShfWcWe9mgzexSWnQCCQ,5295
|
29
29
|
prediction_market_agent_tooling/markets/manifold/manifold.py,sha256=EwRL06E2Y_ZAzr8efwS5yD6p6rnykrcBhqmNDUGZ8Aw,4075
|
30
30
|
prediction_market_agent_tooling/markets/manifold/utils.py,sha256=cPPFWXm3vCYH1jy7_ctJZuQH9ZDaPL4_AgAYzGWkoow,513
|
31
31
|
prediction_market_agent_tooling/markets/markets.py,sha256=w05Oo7yCA2axpCw69Q9y4i9Gcdpht0u5bZGbWqld3rU,2964
|
@@ -44,7 +44,7 @@ prediction_market_agent_tooling/monitor/langfuse/langfuse_wrapper.py,sha256=b6T6
|
|
44
44
|
prediction_market_agent_tooling/monitor/markets/manifold.py,sha256=GdYpgRX1GahDi-75Mr53jgtEg6nWcs_rHDUkg4o_7dQ,3352
|
45
45
|
prediction_market_agent_tooling/monitor/markets/omen.py,sha256=jOLPnIbDU9syjnYtHfOb2xa6-Ize3vbplgh-8WWkuT4,3323
|
46
46
|
prediction_market_agent_tooling/monitor/markets/polymarket.py,sha256=I9z9aO1wncyGI3a09ihrw17JkeBKjAuMmC0I9pl_9o4,1781
|
47
|
-
prediction_market_agent_tooling/monitor/monitor.py,sha256=
|
47
|
+
prediction_market_agent_tooling/monitor/monitor.py,sha256=uJdaEpGWp4VcejoQLF0uOxhV75AhrXNyWPVG38gBeOo,14505
|
48
48
|
prediction_market_agent_tooling/monitor/monitor_app.py,sha256=rDxgdDJqSK0ARx0TJFMkS76npkHZJz0__Rp0xTpiRok,4611
|
49
49
|
prediction_market_agent_tooling/monitor/monitor_settings.py,sha256=Xiozs3AsufuJ04JOe1vjUri-IAMWHjjmc2ugGGiHNH4,947
|
50
50
|
prediction_market_agent_tooling/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -63,10 +63,11 @@ prediction_market_agent_tooling/tools/is_predictable.py,sha256=yRSkmu4lZqrSje9QG
|
|
63
63
|
prediction_market_agent_tooling/tools/parallelism.py,sha256=8mgkF5sBwFGS5GMvlpzam82Y3p2swPYuNsywpQuy-a4,1508
|
64
64
|
prediction_market_agent_tooling/tools/safe.py,sha256=h0xOO0eNtitClf0fPkn-0oTc6A_bflDTee98V_aiV-A,5195
|
65
65
|
prediction_market_agent_tooling/tools/singleton.py,sha256=CiIELUiI-OeS7U7eeHEt0rnVhtQGzwoUdAgn_7u_GBM,729
|
66
|
+
prediction_market_agent_tooling/tools/streamlit_user_login.py,sha256=NXEqfjT9Lc9QtliwSGRASIz1opjQ7Btme43H4qJbzgE,3010
|
66
67
|
prediction_market_agent_tooling/tools/utils.py,sha256=zkmwPi3YisgZDPCeNwaRbL8sInOYOkvFgFY4Q8PbEo4,5077
|
67
68
|
prediction_market_agent_tooling/tools/web3_utils.py,sha256=cboATXNmEdn5RmPbVblHOwOdUMKBYrUK3GiI6i6Vzxo,9855
|
68
|
-
prediction_market_agent_tooling-0.
|
69
|
-
prediction_market_agent_tooling-0.
|
70
|
-
prediction_market_agent_tooling-0.
|
71
|
-
prediction_market_agent_tooling-0.
|
72
|
-
prediction_market_agent_tooling-0.
|
69
|
+
prediction_market_agent_tooling-0.34.0.dist-info/LICENSE,sha256=6or154nLLU6bELzjh0mCreFjt0m2v72zLi3yHE0QbeE,7650
|
70
|
+
prediction_market_agent_tooling-0.34.0.dist-info/METADATA,sha256=Ih-qmKV0wWypWJv0ABswvSd1VSPOJBQwDiXw714KSx0,7515
|
71
|
+
prediction_market_agent_tooling-0.34.0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
72
|
+
prediction_market_agent_tooling-0.34.0.dist-info/entry_points.txt,sha256=m8PukHbeH5g0IAAmOf_1Ahm-sGAMdhSSRQmwtpmi2s8,81
|
73
|
+
prediction_market_agent_tooling-0.34.0.dist-info/RECORD,,
|
File without changes
|
File without changes
|