prediction-market-agent-tooling 0.14.1__tar.gz → 0.15.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.
- {prediction_market_agent_tooling-0.14.1 → prediction_market_agent_tooling-0.15.0}/PKG-INFO +13 -1
- {prediction_market_agent_tooling-0.14.1 → prediction_market_agent_tooling-0.15.0}/README.md +8 -0
- prediction_market_agent_tooling-0.15.0/prediction_market_agent_tooling/abis/erc20.abi.json +315 -0
- {prediction_market_agent_tooling-0.14.1 → prediction_market_agent_tooling-0.15.0}/prediction_market_agent_tooling/benchmark/agents.py +7 -1
- {prediction_market_agent_tooling-0.14.1 → prediction_market_agent_tooling-0.15.0}/prediction_market_agent_tooling/benchmark/benchmark.py +22 -24
- {prediction_market_agent_tooling-0.14.1 → prediction_market_agent_tooling-0.15.0}/prediction_market_agent_tooling/config.py +27 -4
- {prediction_market_agent_tooling-0.14.1 → prediction_market_agent_tooling-0.15.0}/prediction_market_agent_tooling/deploy/agent.py +3 -3
- {prediction_market_agent_tooling-0.14.1 → prediction_market_agent_tooling-0.15.0}/prediction_market_agent_tooling/markets/agent_market.py +20 -9
- {prediction_market_agent_tooling-0.14.1 → prediction_market_agent_tooling-0.15.0}/prediction_market_agent_tooling/markets/manifold/manifold.py +9 -1
- {prediction_market_agent_tooling-0.14.1 → prediction_market_agent_tooling-0.15.0}/prediction_market_agent_tooling/markets/omen/data_models.py +42 -11
- {prediction_market_agent_tooling-0.14.1 → prediction_market_agent_tooling-0.15.0}/prediction_market_agent_tooling/markets/omen/omen.py +135 -52
- {prediction_market_agent_tooling-0.14.1 → prediction_market_agent_tooling-0.15.0}/prediction_market_agent_tooling/markets/omen/omen_contracts.py +36 -34
- {prediction_market_agent_tooling-0.14.1 → prediction_market_agent_tooling-0.15.0}/prediction_market_agent_tooling/markets/omen/omen_replicate.py +11 -16
- {prediction_market_agent_tooling-0.14.1 → prediction_market_agent_tooling-0.15.0}/prediction_market_agent_tooling/markets/omen/omen_resolve_replicated.py +32 -25
- {prediction_market_agent_tooling-0.14.1 → prediction_market_agent_tooling-0.15.0}/prediction_market_agent_tooling/markets/omen/omen_subgraph_handler.py +46 -13
- {prediction_market_agent_tooling-0.14.1 → prediction_market_agent_tooling-0.15.0}/prediction_market_agent_tooling/markets/polymarket/polymarket.py +1 -1
- {prediction_market_agent_tooling-0.14.1 → prediction_market_agent_tooling-0.15.0}/prediction_market_agent_tooling/monitor/markets/omen.py +5 -3
- {prediction_market_agent_tooling-0.14.1 → prediction_market_agent_tooling-0.15.0}/prediction_market_agent_tooling/monitor/markets/polymarket.py +3 -2
- {prediction_market_agent_tooling-0.14.1 → prediction_market_agent_tooling-0.15.0}/prediction_market_agent_tooling/monitor/monitor.py +26 -20
- {prediction_market_agent_tooling-0.14.1 → prediction_market_agent_tooling-0.15.0}/prediction_market_agent_tooling/tools/betting_strategies/minimum_bet_to_win.py +1 -1
- {prediction_market_agent_tooling-0.14.1 → prediction_market_agent_tooling-0.15.0}/prediction_market_agent_tooling/tools/contract.py +32 -17
- prediction_market_agent_tooling-0.15.0/prediction_market_agent_tooling/tools/costs.py +31 -0
- {prediction_market_agent_tooling-0.14.1 → prediction_market_agent_tooling-0.15.0}/prediction_market_agent_tooling/tools/parallelism.py +16 -1
- prediction_market_agent_tooling-0.15.0/prediction_market_agent_tooling/tools/safe.py +130 -0
- {prediction_market_agent_tooling-0.14.1 → prediction_market_agent_tooling-0.15.0}/prediction_market_agent_tooling/tools/web3_utils.py +100 -15
- {prediction_market_agent_tooling-0.14.1 → prediction_market_agent_tooling-0.15.0}/pyproject.toml +5 -1
- {prediction_market_agent_tooling-0.14.1 → prediction_market_agent_tooling-0.15.0}/LICENSE +0 -0
- {prediction_market_agent_tooling-0.14.1 → prediction_market_agent_tooling-0.15.0}/prediction_market_agent_tooling/abis/omen_dxdao.abi.json +0 -0
- {prediction_market_agent_tooling-0.14.1 → prediction_market_agent_tooling-0.15.0}/prediction_market_agent_tooling/abis/omen_fpmm.abi.json +0 -0
- {prediction_market_agent_tooling-0.14.1 → prediction_market_agent_tooling-0.15.0}/prediction_market_agent_tooling/abis/omen_fpmm_conditionaltokens.abi.json +0 -0
- {prediction_market_agent_tooling-0.14.1 → prediction_market_agent_tooling-0.15.0}/prediction_market_agent_tooling/abis/omen_fpmm_factory.abi.json +0 -0
- {prediction_market_agent_tooling-0.14.1 → prediction_market_agent_tooling-0.15.0}/prediction_market_agent_tooling/abis/omen_kleros.abi.json +0 -0
- {prediction_market_agent_tooling-0.14.1 → prediction_market_agent_tooling-0.15.0}/prediction_market_agent_tooling/abis/omen_oracle.abi.json +0 -0
- {prediction_market_agent_tooling-0.14.1 → prediction_market_agent_tooling-0.15.0}/prediction_market_agent_tooling/abis/omen_realitio.abi.json +0 -0
- {prediction_market_agent_tooling-0.14.1 → prediction_market_agent_tooling-0.15.0}/prediction_market_agent_tooling/abis/wxdai.abi.json +0 -0
- {prediction_market_agent_tooling-0.14.1 → prediction_market_agent_tooling-0.15.0}/prediction_market_agent_tooling/benchmark/__init__.py +0 -0
- {prediction_market_agent_tooling-0.14.1 → prediction_market_agent_tooling-0.15.0}/prediction_market_agent_tooling/benchmark/utils.py +0 -0
- {prediction_market_agent_tooling-0.14.1 → prediction_market_agent_tooling-0.15.0}/prediction_market_agent_tooling/deploy/agent_example.py +0 -0
- {prediction_market_agent_tooling-0.14.1 → prediction_market_agent_tooling-0.15.0}/prediction_market_agent_tooling/deploy/constants.py +0 -0
- {prediction_market_agent_tooling-0.14.1 → prediction_market_agent_tooling-0.15.0}/prediction_market_agent_tooling/deploy/gcp/deploy.py +0 -0
- {prediction_market_agent_tooling-0.14.1 → prediction_market_agent_tooling-0.15.0}/prediction_market_agent_tooling/deploy/gcp/kubernetes_models.py +0 -0
- {prediction_market_agent_tooling-0.14.1 → prediction_market_agent_tooling-0.15.0}/prediction_market_agent_tooling/deploy/gcp/utils.py +0 -0
- {prediction_market_agent_tooling-0.14.1 → prediction_market_agent_tooling-0.15.0}/prediction_market_agent_tooling/gtypes.py +0 -0
- {prediction_market_agent_tooling-0.14.1 → prediction_market_agent_tooling-0.15.0}/prediction_market_agent_tooling/markets/categorize.py +0 -0
- {prediction_market_agent_tooling-0.14.1 → prediction_market_agent_tooling-0.15.0}/prediction_market_agent_tooling/markets/data_models.py +0 -0
- {prediction_market_agent_tooling-0.14.1 → prediction_market_agent_tooling-0.15.0}/prediction_market_agent_tooling/markets/manifold/__init__.py +0 -0
- {prediction_market_agent_tooling-0.14.1 → prediction_market_agent_tooling-0.15.0}/prediction_market_agent_tooling/markets/manifold/api.py +0 -0
- {prediction_market_agent_tooling-0.14.1 → prediction_market_agent_tooling-0.15.0}/prediction_market_agent_tooling/markets/manifold/data_models.py +0 -0
- {prediction_market_agent_tooling-0.14.1 → prediction_market_agent_tooling-0.15.0}/prediction_market_agent_tooling/markets/manifold/utils.py +0 -0
- {prediction_market_agent_tooling-0.14.1 → prediction_market_agent_tooling-0.15.0}/prediction_market_agent_tooling/markets/markets.py +0 -0
- {prediction_market_agent_tooling-0.14.1 → prediction_market_agent_tooling-0.15.0}/prediction_market_agent_tooling/markets/omen/__init__.py +0 -0
- {prediction_market_agent_tooling-0.14.1 → prediction_market_agent_tooling-0.15.0}/prediction_market_agent_tooling/markets/polymarket/api.py +0 -0
- {prediction_market_agent_tooling-0.14.1 → prediction_market_agent_tooling-0.15.0}/prediction_market_agent_tooling/markets/polymarket/data_models.py +0 -0
- {prediction_market_agent_tooling-0.14.1 → prediction_market_agent_tooling-0.15.0}/prediction_market_agent_tooling/markets/polymarket/data_models_web.py +0 -0
- {prediction_market_agent_tooling-0.14.1 → prediction_market_agent_tooling-0.15.0}/prediction_market_agent_tooling/markets/polymarket/utils.py +0 -0
- {prediction_market_agent_tooling-0.14.1 → prediction_market_agent_tooling-0.15.0}/prediction_market_agent_tooling/monitor/markets/manifold.py +0 -0
- {prediction_market_agent_tooling-0.14.1 → prediction_market_agent_tooling-0.15.0}/prediction_market_agent_tooling/monitor/monitor_app.py +0 -0
- {prediction_market_agent_tooling-0.14.1 → prediction_market_agent_tooling-0.15.0}/prediction_market_agent_tooling/monitor/monitor_settings.py +0 -0
- {prediction_market_agent_tooling-0.14.1 → prediction_market_agent_tooling-0.15.0}/prediction_market_agent_tooling/py.typed +0 -0
- {prediction_market_agent_tooling-0.14.1 → prediction_market_agent_tooling-0.15.0}/prediction_market_agent_tooling/tools/balances.py +0 -0
- {prediction_market_agent_tooling-0.14.1 → prediction_market_agent_tooling-0.15.0}/prediction_market_agent_tooling/tools/betting_strategies/kelly_criterion.py +0 -0
- {prediction_market_agent_tooling-0.14.1 → prediction_market_agent_tooling-0.15.0}/prediction_market_agent_tooling/tools/betting_strategies/market_moving.py +0 -0
- {prediction_market_agent_tooling-0.14.1 → prediction_market_agent_tooling-0.15.0}/prediction_market_agent_tooling/tools/betting_strategies/stretch_bet_between.py +0 -0
- {prediction_market_agent_tooling-0.14.1 → prediction_market_agent_tooling-0.15.0}/prediction_market_agent_tooling/tools/cache.py +0 -0
- {prediction_market_agent_tooling-0.14.1 → prediction_market_agent_tooling-0.15.0}/prediction_market_agent_tooling/tools/gnosis_rpc.py +0 -0
- {prediction_market_agent_tooling-0.14.1 → prediction_market_agent_tooling-0.15.0}/prediction_market_agent_tooling/tools/google.py +0 -0
- {prediction_market_agent_tooling-0.14.1 → prediction_market_agent_tooling-0.15.0}/prediction_market_agent_tooling/tools/hexbytes_custom.py +0 -0
- {prediction_market_agent_tooling-0.14.1 → prediction_market_agent_tooling-0.15.0}/prediction_market_agent_tooling/tools/is_predictable.py +0 -0
- {prediction_market_agent_tooling-0.14.1 → prediction_market_agent_tooling-0.15.0}/prediction_market_agent_tooling/tools/singleton.py +0 -0
- {prediction_market_agent_tooling-0.14.1 → prediction_market_agent_tooling-0.15.0}/prediction_market_agent_tooling/tools/utils.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: prediction-market-agent-tooling
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.15.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
|
@@ -11,6 +11,7 @@ Provides-Extra: google
|
|
11
11
|
Provides-Extra: langchain
|
12
12
|
Requires-Dist: autoflake (>=2.2.1,<3.0.0)
|
13
13
|
Requires-Dist: cron-validator (>=1.0.8,<2.0.0)
|
14
|
+
Requires-Dist: eth-account (>=0.8.0,<0.9.0)
|
14
15
|
Requires-Dist: eth-typing (>=3.0.0,<4.0.0)
|
15
16
|
Requires-Dist: functions-framework (>=3.5.0,<4.0.0)
|
16
17
|
Requires-Dist: google-api-python-client (==2.95.0) ; extra == "google"
|
@@ -24,8 +25,11 @@ Requires-Dist: langchain-openai (>=0.0.5,<0.0.6) ; extra == "langchain"
|
|
24
25
|
Requires-Dist: loguru (>=0.7.2,<0.8.0)
|
25
26
|
Requires-Dist: mech-client (>=0.2.13,<0.3.0)
|
26
27
|
Requires-Dist: numpy (>=1.26.4,<2.0.0)
|
28
|
+
Requires-Dist: prompt-toolkit (>=3.0.43,<4.0.0)
|
27
29
|
Requires-Dist: pydantic (>=2.6.1,<3.0.0)
|
28
30
|
Requires-Dist: pydantic-settings (>=2.1.0,<3.0.0)
|
31
|
+
Requires-Dist: safe-cli (>=1.0.0,<2.0.0)
|
32
|
+
Requires-Dist: safe-eth-py (>=6.0.0b14,<7.0.0)
|
29
33
|
Requires-Dist: scikit-learn (>=1.4.0,<2.0.0)
|
30
34
|
Requires-Dist: streamlit (>=1.31.0,<2.0.0)
|
31
35
|
Requires-Dist: subgrounds (>=1.8.1,<2.0.0)
|
@@ -104,6 +108,14 @@ class DeployableCoinFlipAgent(DeployableAgent):
|
|
104
108
|
DeployableCoinFlipAgent().deploy_gcp(...)
|
105
109
|
```
|
106
110
|
|
111
|
+
For deploying a Safe manually for a given agent, run the script below:
|
112
|
+
|
113
|
+
```commandline
|
114
|
+
poetry run python scripts/create_safe_for_agent.py --from-private-key <YOUR_AGENT_PRIVATE_KEY> --salt-nonce 42
|
115
|
+
```
|
116
|
+
This will output the newly created Safe in the terminal, and it can then be copied over to the deployment part (e.g. Terraform).
|
117
|
+
Note that `salt_nonce` can be passed so that the created safe is deterministically created for each agent, so that, if the same `salt_nonce` is used, the script will not create a new Safe for the agent, instead it will output the previously existent Safe.
|
118
|
+
|
107
119
|
## Monitoring
|
108
120
|
|
109
121
|
Monitor the performance of the agents deployed to GCP, as well as meta-metrics of the prediction market platforms they are deployed to.
|
@@ -65,6 +65,14 @@ class DeployableCoinFlipAgent(DeployableAgent):
|
|
65
65
|
DeployableCoinFlipAgent().deploy_gcp(...)
|
66
66
|
```
|
67
67
|
|
68
|
+
For deploying a Safe manually for a given agent, run the script below:
|
69
|
+
|
70
|
+
```commandline
|
71
|
+
poetry run python scripts/create_safe_for_agent.py --from-private-key <YOUR_AGENT_PRIVATE_KEY> --salt-nonce 42
|
72
|
+
```
|
73
|
+
This will output the newly created Safe in the terminal, and it can then be copied over to the deployment part (e.g. Terraform).
|
74
|
+
Note that `salt_nonce` can be passed so that the created safe is deterministically created for each agent, so that, if the same `salt_nonce` is used, the script will not create a new Safe for the agent, instead it will output the previously existent Safe.
|
75
|
+
|
68
76
|
## Monitoring
|
69
77
|
|
70
78
|
Monitor the performance of the agents deployed to GCP, as well as meta-metrics of the prediction market platforms they are deployed to.
|
@@ -0,0 +1,315 @@
|
|
1
|
+
[
|
2
|
+
{
|
3
|
+
"inputs": [],
|
4
|
+
"stateMutability": "nonpayable",
|
5
|
+
"type": "constructor"
|
6
|
+
},
|
7
|
+
{
|
8
|
+
"inputs": [
|
9
|
+
{
|
10
|
+
"internalType": "address",
|
11
|
+
"name": "spender",
|
12
|
+
"type": "address"
|
13
|
+
},
|
14
|
+
{
|
15
|
+
"internalType": "uint256",
|
16
|
+
"name": "allowance",
|
17
|
+
"type": "uint256"
|
18
|
+
},
|
19
|
+
{
|
20
|
+
"internalType": "uint256",
|
21
|
+
"name": "needed",
|
22
|
+
"type": "uint256"
|
23
|
+
}
|
24
|
+
],
|
25
|
+
"name": "ERC20InsufficientAllowance",
|
26
|
+
"type": "error"
|
27
|
+
},
|
28
|
+
{
|
29
|
+
"inputs": [
|
30
|
+
{
|
31
|
+
"internalType": "address",
|
32
|
+
"name": "sender",
|
33
|
+
"type": "address"
|
34
|
+
},
|
35
|
+
{
|
36
|
+
"internalType": "uint256",
|
37
|
+
"name": "balance",
|
38
|
+
"type": "uint256"
|
39
|
+
},
|
40
|
+
{
|
41
|
+
"internalType": "uint256",
|
42
|
+
"name": "needed",
|
43
|
+
"type": "uint256"
|
44
|
+
}
|
45
|
+
],
|
46
|
+
"name": "ERC20InsufficientBalance",
|
47
|
+
"type": "error"
|
48
|
+
},
|
49
|
+
{
|
50
|
+
"inputs": [
|
51
|
+
{
|
52
|
+
"internalType": "address",
|
53
|
+
"name": "approver",
|
54
|
+
"type": "address"
|
55
|
+
}
|
56
|
+
],
|
57
|
+
"name": "ERC20InvalidApprover",
|
58
|
+
"type": "error"
|
59
|
+
},
|
60
|
+
{
|
61
|
+
"inputs": [
|
62
|
+
{
|
63
|
+
"internalType": "address",
|
64
|
+
"name": "receiver",
|
65
|
+
"type": "address"
|
66
|
+
}
|
67
|
+
],
|
68
|
+
"name": "ERC20InvalidReceiver",
|
69
|
+
"type": "error"
|
70
|
+
},
|
71
|
+
{
|
72
|
+
"inputs": [
|
73
|
+
{
|
74
|
+
"internalType": "address",
|
75
|
+
"name": "sender",
|
76
|
+
"type": "address"
|
77
|
+
}
|
78
|
+
],
|
79
|
+
"name": "ERC20InvalidSender",
|
80
|
+
"type": "error"
|
81
|
+
},
|
82
|
+
{
|
83
|
+
"inputs": [
|
84
|
+
{
|
85
|
+
"internalType": "address",
|
86
|
+
"name": "spender",
|
87
|
+
"type": "address"
|
88
|
+
}
|
89
|
+
],
|
90
|
+
"name": "ERC20InvalidSpender",
|
91
|
+
"type": "error"
|
92
|
+
},
|
93
|
+
{
|
94
|
+
"anonymous": False,
|
95
|
+
"inputs": [
|
96
|
+
{
|
97
|
+
"indexed": True,
|
98
|
+
"internalType": "address",
|
99
|
+
"name": "owner",
|
100
|
+
"type": "address"
|
101
|
+
},
|
102
|
+
{
|
103
|
+
"indexed": True,
|
104
|
+
"internalType": "address",
|
105
|
+
"name": "spender",
|
106
|
+
"type": "address"
|
107
|
+
},
|
108
|
+
{
|
109
|
+
"indexed": False,
|
110
|
+
"internalType": "uint256",
|
111
|
+
"name": "value",
|
112
|
+
"type": "uint256"
|
113
|
+
}
|
114
|
+
],
|
115
|
+
"name": "Approval",
|
116
|
+
"type": "event"
|
117
|
+
},
|
118
|
+
{
|
119
|
+
"anonymous": False,
|
120
|
+
"inputs": [
|
121
|
+
{
|
122
|
+
"indexed": True,
|
123
|
+
"internalType": "address",
|
124
|
+
"name": "from",
|
125
|
+
"type": "address"
|
126
|
+
},
|
127
|
+
{
|
128
|
+
"indexed": True,
|
129
|
+
"internalType": "address",
|
130
|
+
"name": "to",
|
131
|
+
"type": "address"
|
132
|
+
},
|
133
|
+
{
|
134
|
+
"indexed": False,
|
135
|
+
"internalType": "uint256",
|
136
|
+
"name": "value",
|
137
|
+
"type": "uint256"
|
138
|
+
}
|
139
|
+
],
|
140
|
+
"name": "Transfer",
|
141
|
+
"type": "event"
|
142
|
+
},
|
143
|
+
{
|
144
|
+
"inputs": [
|
145
|
+
{
|
146
|
+
"internalType": "address",
|
147
|
+
"name": "owner",
|
148
|
+
"type": "address"
|
149
|
+
},
|
150
|
+
{
|
151
|
+
"internalType": "address",
|
152
|
+
"name": "spender",
|
153
|
+
"type": "address"
|
154
|
+
}
|
155
|
+
],
|
156
|
+
"name": "allowance",
|
157
|
+
"outputs": [
|
158
|
+
{
|
159
|
+
"internalType": "uint256",
|
160
|
+
"name": "",
|
161
|
+
"type": "uint256"
|
162
|
+
}
|
163
|
+
],
|
164
|
+
"stateMutability": "view",
|
165
|
+
"type": "function"
|
166
|
+
},
|
167
|
+
{
|
168
|
+
"inputs": [
|
169
|
+
{
|
170
|
+
"internalType": "address",
|
171
|
+
"name": "spender",
|
172
|
+
"type": "address"
|
173
|
+
},
|
174
|
+
{
|
175
|
+
"internalType": "uint256",
|
176
|
+
"name": "value",
|
177
|
+
"type": "uint256"
|
178
|
+
}
|
179
|
+
],
|
180
|
+
"name": "approve",
|
181
|
+
"outputs": [
|
182
|
+
{
|
183
|
+
"internalType": "bool",
|
184
|
+
"name": "",
|
185
|
+
"type": "bool"
|
186
|
+
}
|
187
|
+
],
|
188
|
+
"stateMutability": "nonpayable",
|
189
|
+
"type": "function"
|
190
|
+
},
|
191
|
+
{
|
192
|
+
"inputs": [
|
193
|
+
{
|
194
|
+
"internalType": "address",
|
195
|
+
"name": "account",
|
196
|
+
"type": "address"
|
197
|
+
}
|
198
|
+
],
|
199
|
+
"name": "balanceOf",
|
200
|
+
"outputs": [
|
201
|
+
{
|
202
|
+
"internalType": "uint256",
|
203
|
+
"name": "",
|
204
|
+
"type": "uint256"
|
205
|
+
}
|
206
|
+
],
|
207
|
+
"stateMutability": "view",
|
208
|
+
"type": "function"
|
209
|
+
},
|
210
|
+
{
|
211
|
+
"inputs": [],
|
212
|
+
"name": "decimals",
|
213
|
+
"outputs": [
|
214
|
+
{
|
215
|
+
"internalType": "uint8",
|
216
|
+
"name": "",
|
217
|
+
"type": "uint8"
|
218
|
+
}
|
219
|
+
],
|
220
|
+
"stateMutability": "view",
|
221
|
+
"type": "function"
|
222
|
+
},
|
223
|
+
{
|
224
|
+
"inputs": [],
|
225
|
+
"name": "name",
|
226
|
+
"outputs": [
|
227
|
+
{
|
228
|
+
"internalType": "string",
|
229
|
+
"name": "",
|
230
|
+
"type": "string"
|
231
|
+
}
|
232
|
+
],
|
233
|
+
"stateMutability": "view",
|
234
|
+
"type": "function"
|
235
|
+
},
|
236
|
+
{
|
237
|
+
"inputs": [],
|
238
|
+
"name": "symbol",
|
239
|
+
"outputs": [
|
240
|
+
{
|
241
|
+
"internalType": "string",
|
242
|
+
"name": "",
|
243
|
+
"type": "string"
|
244
|
+
}
|
245
|
+
],
|
246
|
+
"stateMutability": "view",
|
247
|
+
"type": "function"
|
248
|
+
},
|
249
|
+
{
|
250
|
+
"inputs": [],
|
251
|
+
"name": "totalSupply",
|
252
|
+
"outputs": [
|
253
|
+
{
|
254
|
+
"internalType": "uint256",
|
255
|
+
"name": "",
|
256
|
+
"type": "uint256"
|
257
|
+
}
|
258
|
+
],
|
259
|
+
"stateMutability": "view",
|
260
|
+
"type": "function"
|
261
|
+
},
|
262
|
+
{
|
263
|
+
"inputs": [
|
264
|
+
{
|
265
|
+
"internalType": "address",
|
266
|
+
"name": "to",
|
267
|
+
"type": "address"
|
268
|
+
},
|
269
|
+
{
|
270
|
+
"internalType": "uint256",
|
271
|
+
"name": "value",
|
272
|
+
"type": "uint256"
|
273
|
+
}
|
274
|
+
],
|
275
|
+
"name": "transfer",
|
276
|
+
"outputs": [
|
277
|
+
{
|
278
|
+
"internalType": "bool",
|
279
|
+
"name": "",
|
280
|
+
"type": "bool"
|
281
|
+
}
|
282
|
+
],
|
283
|
+
"stateMutability": "nonpayable",
|
284
|
+
"type": "function"
|
285
|
+
},
|
286
|
+
{
|
287
|
+
"inputs": [
|
288
|
+
{
|
289
|
+
"internalType": "address",
|
290
|
+
"name": "from",
|
291
|
+
"type": "address"
|
292
|
+
},
|
293
|
+
{
|
294
|
+
"internalType": "address",
|
295
|
+
"name": "to",
|
296
|
+
"type": "address"
|
297
|
+
},
|
298
|
+
{
|
299
|
+
"internalType": "uint256",
|
300
|
+
"name": "value",
|
301
|
+
"type": "uint256"
|
302
|
+
}
|
303
|
+
],
|
304
|
+
"name": "transferFrom",
|
305
|
+
"outputs": [
|
306
|
+
{
|
307
|
+
"internalType": "bool",
|
308
|
+
"name": "",
|
309
|
+
"type": "bool"
|
310
|
+
}
|
311
|
+
],
|
312
|
+
"stateMutability": "nonpayable",
|
313
|
+
"type": "function"
|
314
|
+
},
|
315
|
+
]
|
@@ -9,7 +9,13 @@ from prediction_market_agent_tooling.benchmark.utils import (
|
|
9
9
|
|
10
10
|
|
11
11
|
class AbstractBenchmarkedAgent:
|
12
|
-
def __init__(
|
12
|
+
def __init__(
|
13
|
+
self,
|
14
|
+
agent_name: str,
|
15
|
+
max_workers: t.Optional[int] = None,
|
16
|
+
model: str | None = None,
|
17
|
+
):
|
18
|
+
self.model = model
|
13
19
|
self.agent_name = agent_name
|
14
20
|
self.max_workers = max_workers # Limit the number of workers that can run this worker in parallel threads
|
15
21
|
|
@@ -1,12 +1,10 @@
|
|
1
1
|
import concurrent.futures
|
2
2
|
import os
|
3
|
-
import time
|
4
3
|
import typing as t
|
5
4
|
from collections import defaultdict
|
6
5
|
|
7
6
|
import numpy as np
|
8
7
|
import pandas as pd
|
9
|
-
from langchain_community.callbacks import get_openai_callback
|
10
8
|
from sklearn.metrics import precision_score, recall_score
|
11
9
|
from tqdm import tqdm
|
12
10
|
|
@@ -15,9 +13,9 @@ from prediction_market_agent_tooling.benchmark.utils import (
|
|
15
13
|
Prediction,
|
16
14
|
PredictionsCache,
|
17
15
|
Resolution,
|
18
|
-
get_llm_api_call_cost,
|
19
16
|
)
|
20
17
|
from prediction_market_agent_tooling.markets.agent_market import AgentMarket
|
18
|
+
from prediction_market_agent_tooling.tools.costs import openai_costs
|
21
19
|
from prediction_market_agent_tooling.tools.utils import (
|
22
20
|
check_not_none,
|
23
21
|
should_not_happen,
|
@@ -129,6 +127,7 @@ class Benchmarker:
|
|
129
127
|
return self.predictions.get_prediction(agent_name=agent_name, question=question)
|
130
128
|
|
131
129
|
def run_agents(self, enable_timing: bool = True) -> None:
|
130
|
+
agent: AbstractBenchmarkedAgent # Fix for mypy issue with tqdm.
|
132
131
|
for agent in tqdm(self.registered_agents, desc="Running agents"):
|
133
132
|
# Filter out cached predictions
|
134
133
|
markets_to_run = [
|
@@ -142,27 +141,21 @@ class Benchmarker:
|
|
142
141
|
def get_prediction_result(
|
143
142
|
market: AgentMarket,
|
144
143
|
) -> tuple[str, Prediction]:
|
145
|
-
with
|
146
|
-
start = time.time()
|
144
|
+
with openai_costs(model=agent.model) as costs:
|
147
145
|
prediction = (
|
148
146
|
agent.check_and_predict(market_question=market.question)
|
149
147
|
if not market.is_resolved()
|
150
|
-
else
|
151
|
-
|
152
|
-
|
148
|
+
else (
|
149
|
+
agent.check_and_predict_restricted(
|
150
|
+
market_question=market.question,
|
151
|
+
time_restriction_up_to=market.created_time, # TODO: Add support for resolved_at and any time in between.
|
152
|
+
)
|
153
|
+
if market.created_time is not None
|
154
|
+
else should_not_happen()
|
153
155
|
)
|
154
156
|
)
|
155
|
-
|
156
|
-
prediction.
|
157
|
-
|
158
|
-
if cb.total_tokens > 0 and cb.total_cost == 0:
|
159
|
-
# TODO: this is a hack to get the cost for an unsupported model
|
160
|
-
cb.total_cost = get_llm_api_call_cost(
|
161
|
-
model=agent.model,
|
162
|
-
prompt_tokens=cb.prompt_tokens,
|
163
|
-
completion_tokens=cb.completion_tokens,
|
164
|
-
)
|
165
|
-
prediction.cost = cb.total_cost
|
157
|
+
prediction.time = costs.time
|
158
|
+
prediction.cost = costs.cost
|
166
159
|
return market.question, prediction
|
167
160
|
|
168
161
|
# Run agents in parallel
|
@@ -208,7 +201,7 @@ class Benchmarker:
|
|
208
201
|
return None
|
209
202
|
mse = sum(
|
210
203
|
[
|
211
|
-
(check_not_none(p.outcome_prediction).p_yes - m.
|
204
|
+
(check_not_none(p.outcome_prediction).p_yes - m.current_p_yes) ** 2
|
212
205
|
for p, m in zip(predictions, markets)
|
213
206
|
]
|
214
207
|
) / len(predictions)
|
@@ -262,7 +255,10 @@ class Benchmarker:
|
|
262
255
|
|
263
256
|
within_range_count = 0
|
264
257
|
for p, m in zip(predictions, markets):
|
265
|
-
if
|
258
|
+
if (
|
259
|
+
abs(check_not_none(p.outcome_prediction).p_yes - m.current_p_yes)
|
260
|
+
<= tolerance
|
261
|
+
):
|
266
262
|
within_range_count += 1
|
267
263
|
|
268
264
|
return (100 * within_range_count) / len(predictions)
|
@@ -330,7 +326,7 @@ class Benchmarker:
|
|
330
326
|
return None
|
331
327
|
|
332
328
|
p_yes_errors = [
|
333
|
-
abs(check_not_none(p.outcome_prediction).p_yes - m.
|
329
|
+
abs(check_not_none(p.outcome_prediction).p_yes - m.current_p_yes)
|
334
330
|
for p, m in zip(predictions, markets)
|
335
331
|
]
|
336
332
|
confidences = [
|
@@ -420,7 +416,7 @@ class Benchmarker:
|
|
420
416
|
for p in agent_predictions
|
421
417
|
]
|
422
418
|
markets_summary[f"reference p_yes"] = [
|
423
|
-
f"{m.
|
419
|
+
f"{m.current_p_yes:.2f} [{m.probable_resolution}]" for m in self.markets
|
424
420
|
]
|
425
421
|
return markets_summary
|
426
422
|
|
@@ -475,7 +471,9 @@ class Benchmarker:
|
|
475
471
|
return None
|
476
472
|
|
477
473
|
expected_value = (
|
478
|
-
yes_shares * market.
|
474
|
+
yes_shares * market.current_p_yes
|
475
|
+
+ no_shares * (1 - market.current_p_yes)
|
476
|
+
- bet_units
|
479
477
|
)
|
480
478
|
expected_returns_perc = 100 * expected_value / bet_units
|
481
479
|
|
@@ -1,5 +1,6 @@
|
|
1
1
|
import typing as t
|
2
2
|
|
3
|
+
from pydantic import BaseModel
|
3
4
|
from pydantic.types import SecretStr
|
4
5
|
from pydantic_settings import BaseSettings, SettingsConfigDict
|
5
6
|
|
@@ -23,6 +24,7 @@ class APIKeys(BaseSettings):
|
|
23
24
|
|
24
25
|
MANIFOLD_API_KEY: t.Optional[SecretStr] = None
|
25
26
|
BET_FROM_PRIVATE_KEY: t.Optional[PrivateKey] = None
|
27
|
+
SAFE_ADDRESS: t.Optional[ChecksumAddress] = None
|
26
28
|
OPENAI_API_KEY: t.Optional[SecretStr] = None
|
27
29
|
|
28
30
|
GOOGLE_SEARCH_API_KEY: t.Optional[SecretStr] = None
|
@@ -43,10 +45,6 @@ class APIKeys(BaseSettings):
|
|
43
45
|
self.MANIFOLD_API_KEY, "MANIFOLD_API_KEY missing in the environment."
|
44
46
|
)
|
45
47
|
|
46
|
-
@property
|
47
|
-
def bet_from_address(self) -> ChecksumAddress:
|
48
|
-
return private_key_to_public_key(self.bet_from_private_key)
|
49
|
-
|
50
48
|
@property
|
51
49
|
def bet_from_private_key(self) -> PrivateKey:
|
52
50
|
return check_not_none(
|
@@ -87,3 +85,28 @@ class APIKeys(BaseSettings):
|
|
87
85
|
for k, v in self.model_dump().items()
|
88
86
|
if APIKeys.model_fields[k].annotation in SECRET_TYPES and v is not None
|
89
87
|
}
|
88
|
+
|
89
|
+
|
90
|
+
class PrivateCredentials(BaseModel):
|
91
|
+
private_key: PrivateKey
|
92
|
+
safe_address: ChecksumAddress | None
|
93
|
+
|
94
|
+
@property
|
95
|
+
def public_key(self) -> ChecksumAddress:
|
96
|
+
"""If the SAFE is available, we always route transactions via SAFE. Otherwise we use the EOA."""
|
97
|
+
return (
|
98
|
+
self.safe_address
|
99
|
+
if self.safe_address is not None
|
100
|
+
else private_key_to_public_key(self.private_key)
|
101
|
+
)
|
102
|
+
|
103
|
+
@property
|
104
|
+
def has_safe_address(self) -> bool:
|
105
|
+
return self.safe_address is not None
|
106
|
+
|
107
|
+
@staticmethod
|
108
|
+
def from_api_keys(api_keys: APIKeys) -> "PrivateCredentials":
|
109
|
+
return PrivateCredentials(
|
110
|
+
private_key=api_keys.bet_from_private_key,
|
111
|
+
safe_address=api_keys.SAFE_ADDRESS,
|
112
|
+
)
|
@@ -7,7 +7,7 @@ from datetime import datetime
|
|
7
7
|
|
8
8
|
from loguru import logger
|
9
9
|
|
10
|
-
from prediction_market_agent_tooling.config import APIKeys
|
10
|
+
from prediction_market_agent_tooling.config import APIKeys, PrivateCredentials
|
11
11
|
from prediction_market_agent_tooling.deploy.constants import (
|
12
12
|
MARKET_TYPE_KEY,
|
13
13
|
REPOSITORY_KEY,
|
@@ -181,11 +181,11 @@ def {entrypoint_function_name}(request) -> str:
|
|
181
181
|
"""
|
182
182
|
Executes actions that occur before bets are placed.
|
183
183
|
"""
|
184
|
-
|
184
|
+
private_credentials = PrivateCredentials.from_api_keys(APIKeys())
|
185
185
|
|
186
186
|
if market_type == MarketType.OMEN:
|
187
187
|
# Omen is specific, because the user (agent) needs to manually withdraw winnings from the market.
|
188
|
-
redeem_from_all_user_positions(
|
188
|
+
redeem_from_all_user_positions(private_credentials)
|
189
189
|
|
190
190
|
def process_bets(self, market_type: MarketType, _place_bet: bool = True) -> None:
|
191
191
|
"""
|
@@ -46,7 +46,7 @@ class AgentMarket(BaseModel):
|
|
46
46
|
resolution: Resolution | None
|
47
47
|
created_time: datetime | None
|
48
48
|
close_time: datetime | None
|
49
|
-
|
49
|
+
current_p_yes: Probability
|
50
50
|
url: str
|
51
51
|
volume: float | None # Should be in currency of `currency` above.
|
52
52
|
|
@@ -58,8 +58,8 @@ class AgentMarket(BaseModel):
|
|
58
58
|
)
|
59
59
|
|
60
60
|
@property
|
61
|
-
def
|
62
|
-
return Probability(1 - self.
|
61
|
+
def current_p_no(self) -> Probability:
|
62
|
+
return Probability(1 - self.current_p_yes)
|
63
63
|
|
64
64
|
@property
|
65
65
|
def yes_outcome_price(self) -> float:
|
@@ -67,7 +67,7 @@ class AgentMarket(BaseModel):
|
|
67
67
|
Price at prediction market is equal to the probability of given outcome.
|
68
68
|
Keep as an extra property, in case it wouldn't be true for some prediction market platform.
|
69
69
|
"""
|
70
|
-
return self.
|
70
|
+
return self.current_p_yes
|
71
71
|
|
72
72
|
@property
|
73
73
|
def no_outcome_price(self) -> float:
|
@@ -75,7 +75,7 @@ class AgentMarket(BaseModel):
|
|
75
75
|
Price at prediction market is equal to the probability of given outcome.
|
76
76
|
Keep as an extra property, in case it wouldn't be true for some prediction market platform.
|
77
77
|
"""
|
78
|
-
return self.
|
78
|
+
return self.current_p_no
|
79
79
|
|
80
80
|
@property
|
81
81
|
def probable_resolution(self) -> Resolution:
|
@@ -85,7 +85,7 @@ class AgentMarket(BaseModel):
|
|
85
85
|
else:
|
86
86
|
raise ValueError(f"Unknown resolution: {self.resolution}")
|
87
87
|
else:
|
88
|
-
return Resolution.YES if self.
|
88
|
+
return Resolution.YES if self.current_p_yes > 0.5 else Resolution.NO
|
89
89
|
|
90
90
|
@property
|
91
91
|
def boolean_outcome(self) -> bool:
|
@@ -96,6 +96,20 @@ class AgentMarket(BaseModel):
|
|
96
96
|
return False
|
97
97
|
should_not_happen(f"Market {self.id} does not have a successful resolution.")
|
98
98
|
|
99
|
+
def get_last_trade_p_yes(self) -> Probability | None:
|
100
|
+
"""
|
101
|
+
Get the last trade price for the YES outcome. This can be different from the current p_yes, for example if market is closed and it's probabilities are fixed to 0 and 1.
|
102
|
+
Could be None if no trades were made.
|
103
|
+
"""
|
104
|
+
raise NotImplementedError("Subclasses must implement this method")
|
105
|
+
|
106
|
+
def get_last_trade_p_no(self) -> Probability | None:
|
107
|
+
"""
|
108
|
+
Get the last trade price for the NO outcome. This can be different from the current p_yes, for example if market is closed and it's probabilities are fixed to 0 and 1.
|
109
|
+
Could be None if no trades were made.
|
110
|
+
"""
|
111
|
+
raise NotImplementedError("Subclasses must implement this method")
|
112
|
+
|
99
113
|
def get_bet_amount(self, amount: float) -> BetAmount:
|
100
114
|
return BetAmount(amount=amount, currency=self.currency)
|
101
115
|
|
@@ -148,9 +162,6 @@ class AgentMarket(BaseModel):
|
|
148
162
|
except ValueError:
|
149
163
|
raise ValueError(f"Outcome `{outcome}` not found in `{self.outcomes}`.")
|
150
164
|
|
151
|
-
def get_squared_error(self) -> float:
|
152
|
-
return (self.p_yes - self.boolean_outcome) ** 2
|
153
|
-
|
154
165
|
def get_token_balance(self, user_id: str, outcome: str) -> TokenAmount:
|
155
166
|
raise NotImplementedError("Subclasses must implement this method")
|
156
167
|
|
@@ -31,6 +31,14 @@ class ManifoldAgentMarket(AgentMarket):
|
|
31
31
|
currency: t.ClassVar[Currency] = Currency.Mana
|
32
32
|
base_url: t.ClassVar[str] = MANIFOLD_BASE_URL
|
33
33
|
|
34
|
+
def get_last_trade_p_yes(self) -> Probability:
|
35
|
+
"""On Manifold, probablities aren't updated after the closure, so we can just use the current probability"""
|
36
|
+
return self.current_p_yes
|
37
|
+
|
38
|
+
def get_last_trade_p_no(self) -> Probability:
|
39
|
+
"""On Manifold, probablities aren't updated after the closure, so we can just use the current probability"""
|
40
|
+
return self.current_p_no
|
41
|
+
|
34
42
|
def get_tiny_bet_amount(self) -> BetAmount:
|
35
43
|
return BetAmount(amount=1, currency=self.currency)
|
36
44
|
|
@@ -57,7 +65,7 @@ class ManifoldAgentMarket(AgentMarket):
|
|
57
65
|
resolution=model.resolution,
|
58
66
|
created_time=model.createdTime,
|
59
67
|
close_time=model.closeTime,
|
60
|
-
|
68
|
+
current_p_yes=model.probability,
|
61
69
|
url=model.url,
|
62
70
|
volume=model.volume,
|
63
71
|
)
|