prediction-market-agent-tooling 0.56.3.dev135__py3-none-any.whl → 0.57.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/config.py +31 -2
- prediction_market_agent_tooling/deploy/agent.py +71 -48
- prediction_market_agent_tooling/markets/data_models.py +21 -0
- prediction_market_agent_tooling/markets/manifold/data_models.py +0 -1
- prediction_market_agent_tooling/markets/omen/data_models.py +11 -10
- prediction_market_agent_tooling/markets/omen/omen.py +2 -1
- prediction_market_agent_tooling/markets/omen/omen_contracts.py +1 -1
- prediction_market_agent_tooling/markets/omen/omen_subgraph_handler.py +8 -4
- prediction_market_agent_tooling/markets/polymarket/utils.py +1 -1
- prediction_market_agent_tooling/monitor/financial_metrics/financial_metrics.py +66 -0
- prediction_market_agent_tooling/monitor/monitor.py +1 -1
- prediction_market_agent_tooling/tools/caches/db_cache.py +9 -75
- prediction_market_agent_tooling/tools/caches/serializers.py +61 -0
- prediction_market_agent_tooling/tools/contract.py +3 -7
- prediction_market_agent_tooling/tools/custom_exceptions.py +6 -0
- prediction_market_agent_tooling/tools/db/db_manager.py +76 -0
- prediction_market_agent_tooling/tools/{google.py → google_utils.py} +28 -1
- prediction_market_agent_tooling/tools/image_gen/market_thumbnail_gen.py +1 -1
- prediction_market_agent_tooling/tools/is_invalid.py +1 -1
- prediction_market_agent_tooling/tools/is_predictable.py +8 -3
- prediction_market_agent_tooling/tools/langfuse_client_utils.py +1 -0
- prediction_market_agent_tooling/tools/relevant_news_analysis/relevant_news_cache.py +7 -14
- prediction_market_agent_tooling/tools/transaction_cache.py +48 -0
- prediction_market_agent_tooling/tools/utils.py +1 -23
- prediction_market_agent_tooling/tools/web3_utils.py +5 -1
- {prediction_market_agent_tooling-0.56.3.dev135.dist-info → prediction_market_agent_tooling-0.57.1.dist-info}/METADATA +1 -1
- {prediction_market_agent_tooling-0.56.3.dev135.dist-info → prediction_market_agent_tooling-0.57.1.dist-info}/RECORD +30 -27
- prediction_market_agent_tooling/tools/gnosis_rpc.py +0 -6
- prediction_market_agent_tooling/tools/pickle_utils.py +0 -31
- {prediction_market_agent_tooling-0.56.3.dev135.dist-info → prediction_market_agent_tooling-0.57.1.dist-info}/LICENSE +0 -0
- {prediction_market_agent_tooling-0.56.3.dev135.dist-info → prediction_market_agent_tooling-0.57.1.dist-info}/WHEEL +0 -0
- {prediction_market_agent_tooling-0.56.3.dev135.dist-info → prediction_market_agent_tooling-0.57.1.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,61 @@
|
|
1
|
+
import json
|
2
|
+
import typing as t
|
3
|
+
from datetime import date, timedelta
|
4
|
+
|
5
|
+
from pydantic import BaseModel
|
6
|
+
|
7
|
+
from prediction_market_agent_tooling.tools.datetime_utc import DatetimeUTC
|
8
|
+
|
9
|
+
|
10
|
+
def json_serializer(x: t.Any) -> str:
|
11
|
+
return json.dumps(x, default=json_serializer_default_fn)
|
12
|
+
|
13
|
+
|
14
|
+
def json_serializer_default_fn(
|
15
|
+
y: DatetimeUTC | timedelta | date | BaseModel,
|
16
|
+
) -> str | dict[str, t.Any]:
|
17
|
+
"""
|
18
|
+
Used to serialize objects that don't support it by default into a specific string that can be deserialized out later.
|
19
|
+
If this function returns a dictionary, it will be called recursivelly.
|
20
|
+
If you add something here, also add it to `replace_custom_stringified_objects` below.
|
21
|
+
"""
|
22
|
+
if isinstance(y, DatetimeUTC):
|
23
|
+
return f"DatetimeUTC::{y.isoformat()}"
|
24
|
+
elif isinstance(y, timedelta):
|
25
|
+
return f"timedelta::{y.total_seconds()}"
|
26
|
+
elif isinstance(y, date):
|
27
|
+
return f"date::{y.isoformat()}"
|
28
|
+
elif isinstance(y, BaseModel):
|
29
|
+
return y.model_dump()
|
30
|
+
raise TypeError(
|
31
|
+
f"Unsuported type for the default json serialize function, value is {y}."
|
32
|
+
)
|
33
|
+
|
34
|
+
|
35
|
+
def json_deserializer(s: str) -> t.Any:
|
36
|
+
data = json.loads(s)
|
37
|
+
return replace_custom_stringified_objects(data)
|
38
|
+
|
39
|
+
|
40
|
+
def replace_custom_stringified_objects(obj: t.Any) -> t.Any:
|
41
|
+
"""
|
42
|
+
Used to deserialize objects from `json_serializer_default_fn` into their proper form.
|
43
|
+
"""
|
44
|
+
if isinstance(obj, str):
|
45
|
+
if obj.startswith("DatetimeUTC::"):
|
46
|
+
iso_str = obj[len("DatetimeUTC::") :]
|
47
|
+
return DatetimeUTC.to_datetime_utc(iso_str)
|
48
|
+
elif obj.startswith("timedelta::"):
|
49
|
+
total_seconds_str = obj[len("timedelta::") :]
|
50
|
+
return timedelta(seconds=float(total_seconds_str))
|
51
|
+
elif obj.startswith("date::"):
|
52
|
+
iso_str = obj[len("date::") :]
|
53
|
+
return date.fromisoformat(iso_str)
|
54
|
+
else:
|
55
|
+
return obj
|
56
|
+
elif isinstance(obj, dict):
|
57
|
+
return {k: replace_custom_stringified_objects(v) for k, v in obj.items()}
|
58
|
+
elif isinstance(obj, list):
|
59
|
+
return [replace_custom_stringified_objects(item) for item in obj]
|
60
|
+
else:
|
61
|
+
return obj
|
@@ -8,7 +8,7 @@ from pydantic import BaseModel, field_validator
|
|
8
8
|
from web3 import Web3
|
9
9
|
from web3.contract.contract import Contract as Web3Contract
|
10
10
|
|
11
|
-
from prediction_market_agent_tooling.config import APIKeys
|
11
|
+
from prediction_market_agent_tooling.config import APIKeys, RPCConfig
|
12
12
|
from prediction_market_agent_tooling.gtypes import (
|
13
13
|
ABI,
|
14
14
|
ChainID,
|
@@ -18,10 +18,6 @@ from prediction_market_agent_tooling.gtypes import (
|
|
18
18
|
TxReceipt,
|
19
19
|
Wei,
|
20
20
|
)
|
21
|
-
from prediction_market_agent_tooling.tools.gnosis_rpc import (
|
22
|
-
GNOSIS_NETWORK_ID,
|
23
|
-
GNOSIS_RPC_URL,
|
24
|
-
)
|
25
21
|
from prediction_market_agent_tooling.tools.utils import DatetimeUTC, should_not_happen
|
26
22
|
from prediction_market_agent_tooling.tools.web3_utils import (
|
27
23
|
call_function_on_contract,
|
@@ -391,8 +387,8 @@ class ContractOnGnosisChain(ContractBaseClass):
|
|
391
387
|
Contract base class with Gnosis Chain configuration.
|
392
388
|
"""
|
393
389
|
|
394
|
-
CHAIN_ID =
|
395
|
-
CHAIN_RPC_URL =
|
390
|
+
CHAIN_ID = RPCConfig().chain_id
|
391
|
+
CHAIN_RPC_URL = RPCConfig().gnosis_rpc_url
|
396
392
|
|
397
393
|
|
398
394
|
class ContractProxyOnGnosisChain(ContractProxyBaseClass, ContractOnGnosisChain):
|
@@ -0,0 +1,76 @@
|
|
1
|
+
import hashlib
|
2
|
+
from contextlib import contextmanager
|
3
|
+
from typing import Generator, Sequence
|
4
|
+
|
5
|
+
from sqlalchemy import Connection
|
6
|
+
from sqlmodel import Session, SQLModel, create_engine
|
7
|
+
|
8
|
+
from prediction_market_agent_tooling.config import APIKeys
|
9
|
+
from prediction_market_agent_tooling.tools.caches.serializers import (
|
10
|
+
json_deserializer,
|
11
|
+
json_serializer,
|
12
|
+
)
|
13
|
+
|
14
|
+
|
15
|
+
class DBManager:
|
16
|
+
_instances: dict[str, "DBManager"] = {}
|
17
|
+
|
18
|
+
def __new__(cls, api_keys: APIKeys | None = None) -> "DBManager":
|
19
|
+
sqlalchemy_db_url = (api_keys or APIKeys()).sqlalchemy_db_url
|
20
|
+
# Hash the secret value to not store secrets in plain text.
|
21
|
+
url_hash = hashlib.md5(
|
22
|
+
sqlalchemy_db_url.get_secret_value().encode()
|
23
|
+
).hexdigest()
|
24
|
+
# Return singleton per database connection.
|
25
|
+
if url_hash not in cls._instances:
|
26
|
+
instance = super(DBManager, cls).__new__(cls)
|
27
|
+
cls._instances[url_hash] = instance
|
28
|
+
return cls._instances[url_hash]
|
29
|
+
|
30
|
+
def __init__(self, api_keys: APIKeys | None = None) -> None:
|
31
|
+
sqlalchemy_db_url = (api_keys or APIKeys()).sqlalchemy_db_url
|
32
|
+
self._engine = create_engine(
|
33
|
+
sqlalchemy_db_url.get_secret_value(),
|
34
|
+
json_serializer=json_serializer,
|
35
|
+
json_deserializer=json_deserializer,
|
36
|
+
pool_size=20,
|
37
|
+
pool_recycle=3600,
|
38
|
+
echo=True,
|
39
|
+
)
|
40
|
+
self.cache_table_initialized: dict[str, bool] = {}
|
41
|
+
|
42
|
+
@contextmanager
|
43
|
+
def get_session(self) -> Generator[Session, None, None]:
|
44
|
+
with Session(self._engine) as session:
|
45
|
+
yield session
|
46
|
+
|
47
|
+
@contextmanager
|
48
|
+
def get_connection(self) -> Generator[Connection, None, None]:
|
49
|
+
with self.get_session() as session:
|
50
|
+
yield session.connection()
|
51
|
+
|
52
|
+
def create_tables(
|
53
|
+
self, sqlmodel_tables: Sequence[type[SQLModel]] | None = None
|
54
|
+
) -> None:
|
55
|
+
# Determine tables to create
|
56
|
+
if sqlmodel_tables is not None:
|
57
|
+
tables_to_create = []
|
58
|
+
for sqlmodel_table in sqlmodel_tables:
|
59
|
+
table_name = (
|
60
|
+
sqlmodel_table.__tablename__()
|
61
|
+
if callable(sqlmodel_table.__tablename__)
|
62
|
+
else sqlmodel_table.__tablename__
|
63
|
+
)
|
64
|
+
table = SQLModel.metadata.tables[table_name]
|
65
|
+
if not self.cache_table_initialized.get(table.name):
|
66
|
+
tables_to_create.append(table)
|
67
|
+
else:
|
68
|
+
tables_to_create = None
|
69
|
+
|
70
|
+
# Create tables in the database
|
71
|
+
SQLModel.metadata.create_all(self._engine, tables=tables_to_create)
|
72
|
+
|
73
|
+
# Update cache to mark tables as initialized
|
74
|
+
if tables_to_create:
|
75
|
+
for table in tables_to_create:
|
76
|
+
self.cache_table_initialized[table.name] = True
|
@@ -1,10 +1,14 @@
|
|
1
|
+
import json
|
1
2
|
import typing as t
|
2
3
|
from datetime import timedelta
|
3
4
|
|
4
5
|
import tenacity
|
6
|
+
from google.cloud import secretmanager
|
5
7
|
from googleapiclient.discovery import build
|
8
|
+
from pydantic import SecretStr
|
6
9
|
|
7
|
-
from prediction_market_agent_tooling.config import APIKeys
|
10
|
+
from prediction_market_agent_tooling.config import APIKeys, CloudCredentials
|
11
|
+
from prediction_market_agent_tooling.gtypes import PrivateKey
|
8
12
|
from prediction_market_agent_tooling.loggers import logger
|
9
13
|
from prediction_market_agent_tooling.tools.caches.db_cache import db_cache
|
10
14
|
|
@@ -51,3 +55,26 @@ def search_google(
|
|
51
55
|
)
|
52
56
|
except KeyError as e:
|
53
57
|
raise ValueError(f"Can not parse results: {search}") from e
|
58
|
+
|
59
|
+
|
60
|
+
def get_private_key_from_gcp_secret(
|
61
|
+
secret_id: str,
|
62
|
+
project_id: str = "582587111398", # Gnosis AI default project_id
|
63
|
+
version_id: str = "latest",
|
64
|
+
) -> PrivateKey:
|
65
|
+
# If credentials filename specified, use that, else read using default credentials path.
|
66
|
+
google_application_credentials_filename = (
|
67
|
+
CloudCredentials().GOOGLE_APPLICATION_CREDENTIALS
|
68
|
+
)
|
69
|
+
if google_application_credentials_filename is not None:
|
70
|
+
# mypy interprets incorrectly that from_service_account_json requires further args.
|
71
|
+
client = secretmanager.SecretManagerServiceClient.from_service_account_json(filename=google_application_credentials_filename) # type: ignore [call-arg]
|
72
|
+
else:
|
73
|
+
client = secretmanager.SecretManagerServiceClient()
|
74
|
+
name = f"projects/{project_id}/secrets/{secret_id}/versions/{version_id}"
|
75
|
+
response = client.access_secret_version(request={"name": name})
|
76
|
+
secret_payload = response.payload.data.decode("UTF-8")
|
77
|
+
secret_json = json.loads(secret_payload)
|
78
|
+
if "private_key" not in secret_json:
|
79
|
+
raise ValueError(f"Private key not found in gcp secret {secret_id}")
|
80
|
+
return PrivateKey(SecretStr(secret_json["private_key"]))
|
@@ -17,7 +17,7 @@ def rewrite_question_into_image_generation_prompt(question: str) -> str:
|
|
17
17
|
"openai not installed, please install extras `langchain` to use this function."
|
18
18
|
)
|
19
19
|
llm = ChatOpenAI(
|
20
|
-
model="gpt-
|
20
|
+
model="gpt-4o-2024-08-06",
|
21
21
|
temperature=0.0,
|
22
22
|
api_key=APIKeys().openai_api_key_secretstr_v1,
|
23
23
|
)
|
@@ -60,7 +60,7 @@ Finally, write your final decision, write `decision: ` followed by either "yes i
|
|
60
60
|
@db_cache
|
61
61
|
def is_invalid(
|
62
62
|
question: str,
|
63
|
-
engine: str = "gpt-4o",
|
63
|
+
engine: str = "gpt-4o-2024-08-06",
|
64
64
|
temperature: float = LLM_SUPER_LOW_TEMPERATURE,
|
65
65
|
seed: int = LLM_SEED,
|
66
66
|
prompt_template: str = QUESTION_IS_INVALID_PROMPT,
|
@@ -7,7 +7,10 @@ from prediction_market_agent_tooling.tools.langfuse_ import (
|
|
7
7
|
get_langfuse_langchain_config,
|
8
8
|
observe,
|
9
9
|
)
|
10
|
-
from prediction_market_agent_tooling.tools.utils import
|
10
|
+
from prediction_market_agent_tooling.tools.utils import (
|
11
|
+
LLM_SEED,
|
12
|
+
LLM_SUPER_LOW_TEMPERATURE,
|
13
|
+
)
|
11
14
|
|
12
15
|
# I tried to make it return a JSON, but it didn't work well in combo with asking it to do chain of thought.
|
13
16
|
QUESTION_IS_PREDICTABLE_BINARY_PROMPT = """Main signs about a fully qualified question (sometimes referred to as a "market"):
|
@@ -81,7 +84,7 @@ Finally, write your final decision, write `decision: ` followed by either "yes i
|
|
81
84
|
@db_cache
|
82
85
|
def is_predictable_binary(
|
83
86
|
question: str,
|
84
|
-
engine: str = "gpt-
|
87
|
+
engine: str = "gpt-4o-2024-08-06",
|
85
88
|
prompt_template: str = QUESTION_IS_PREDICTABLE_BINARY_PROMPT,
|
86
89
|
max_tokens: int = 1024,
|
87
90
|
) -> bool:
|
@@ -98,6 +101,7 @@ def is_predictable_binary(
|
|
98
101
|
llm = ChatOpenAI(
|
99
102
|
model=engine,
|
100
103
|
temperature=LLM_SUPER_LOW_TEMPERATURE,
|
104
|
+
seed=LLM_SEED,
|
101
105
|
api_key=APIKeys().openai_api_key_secretstr_v1,
|
102
106
|
)
|
103
107
|
|
@@ -118,7 +122,7 @@ def is_predictable_binary(
|
|
118
122
|
def is_predictable_without_description(
|
119
123
|
question: str,
|
120
124
|
description: str,
|
121
|
-
engine: str = "gpt-
|
125
|
+
engine: str = "gpt-4o-2024-08-06",
|
122
126
|
prompt_template: str = QUESTION_IS_PREDICTABLE_WITHOUT_DESCRIPTION_PROMPT,
|
123
127
|
max_tokens: int = 1024,
|
124
128
|
) -> bool:
|
@@ -137,6 +141,7 @@ def is_predictable_without_description(
|
|
137
141
|
llm = ChatOpenAI(
|
138
142
|
model=engine,
|
139
143
|
temperature=LLM_SUPER_LOW_TEMPERATURE,
|
144
|
+
seed=LLM_SEED,
|
140
145
|
api_key=APIKeys().openai_api_key_secretstr_v1,
|
141
146
|
)
|
142
147
|
|
@@ -1,10 +1,11 @@
|
|
1
1
|
from datetime import datetime, timedelta
|
2
2
|
|
3
3
|
from pydantic import ValidationError
|
4
|
-
from sqlmodel import Field,
|
4
|
+
from sqlmodel import Field, SQLModel, desc, select
|
5
5
|
|
6
6
|
from prediction_market_agent_tooling.config import APIKeys
|
7
7
|
from prediction_market_agent_tooling.loggers import logger
|
8
|
+
from prediction_market_agent_tooling.tools.db.db_manager import DBManager
|
8
9
|
from prediction_market_agent_tooling.tools.relevant_news_analysis.data_models import (
|
9
10
|
NoRelevantNews,
|
10
11
|
RelevantNews,
|
@@ -23,30 +24,22 @@ class RelevantNewsCacheModel(SQLModel, table=True):
|
|
23
24
|
|
24
25
|
|
25
26
|
class RelevantNewsResponseCache:
|
26
|
-
def __init__(self,
|
27
|
-
self.
|
28
|
-
sqlalchemy_db_url
|
29
|
-
if sqlalchemy_db_url
|
30
|
-
else APIKeys().sqlalchemy_db_url.get_secret_value()
|
31
|
-
)
|
27
|
+
def __init__(self, api_keys: APIKeys | None = None):
|
28
|
+
self.db_manager = DBManager(api_keys)
|
32
29
|
self._initialize_db()
|
33
30
|
|
34
31
|
def _initialize_db(self) -> None:
|
35
32
|
"""
|
36
33
|
Creates the tables if they don't exist
|
37
34
|
"""
|
38
|
-
|
39
|
-
SQLModel.metadata.create_all(
|
40
|
-
conn,
|
41
|
-
tables=[SQLModel.metadata.tables[RelevantNewsCacheModel.__tablename__]],
|
42
|
-
)
|
35
|
+
self.db_manager.create_tables([RelevantNewsCacheModel])
|
43
36
|
|
44
37
|
def find(
|
45
38
|
self,
|
46
39
|
question: str,
|
47
40
|
days_ago: int,
|
48
41
|
) -> RelevantNews | NoRelevantNews | None:
|
49
|
-
with
|
42
|
+
with self.db_manager.get_session() as session:
|
50
43
|
query = (
|
51
44
|
select(RelevantNewsCacheModel)
|
52
45
|
.where(RelevantNewsCacheModel.question == question)
|
@@ -79,7 +72,7 @@ class RelevantNewsResponseCache:
|
|
79
72
|
days_ago: int,
|
80
73
|
relevant_news: RelevantNews | None,
|
81
74
|
) -> None:
|
82
|
-
with
|
75
|
+
with self.db_manager.get_session() as session:
|
83
76
|
cached = RelevantNewsCacheModel(
|
84
77
|
question=question,
|
85
78
|
days_ago=days_ago,
|
@@ -0,0 +1,48 @@
|
|
1
|
+
import diskcache as dc
|
2
|
+
import tenacity
|
3
|
+
from eth_typing import HexStr
|
4
|
+
from tenacity import wait_exponential
|
5
|
+
from web3 import Web3
|
6
|
+
|
7
|
+
from prediction_market_agent_tooling.loggers import logger
|
8
|
+
|
9
|
+
|
10
|
+
class TransactionBlockCache:
|
11
|
+
def __init__(self, web3: Web3):
|
12
|
+
self.block_number_cache = dc.Cache("block_cache_dir")
|
13
|
+
self.block_timestamp_cache = dc.Cache("timestamp_cache_dir")
|
14
|
+
self.web3 = web3
|
15
|
+
|
16
|
+
@tenacity.retry(
|
17
|
+
wait=wait_exponential(multiplier=1, min=1, max=4),
|
18
|
+
stop=tenacity.stop_after_attempt(7),
|
19
|
+
after=lambda x: logger.debug(f"fetch tx failed, {x.attempt_number=}."),
|
20
|
+
)
|
21
|
+
def fetch_block_number(self, transaction_hash: str) -> int:
|
22
|
+
tx = self.web3.eth.get_transaction(HexStr(transaction_hash))
|
23
|
+
return tx["blockNumber"]
|
24
|
+
|
25
|
+
@tenacity.retry(
|
26
|
+
wait=wait_exponential(multiplier=1, min=1, max=4),
|
27
|
+
stop=tenacity.stop_after_attempt(7),
|
28
|
+
after=lambda x: logger.debug(f"fetch tx failed, {x.attempt_number=}."),
|
29
|
+
)
|
30
|
+
def fetch_block_timestamp(self, block_number: int) -> int:
|
31
|
+
block = self.web3.eth.get_block(block_number)
|
32
|
+
return block["timestamp"]
|
33
|
+
|
34
|
+
def get_block_number(self, tx_hash: str) -> int:
|
35
|
+
if tx_hash in self.block_number_cache:
|
36
|
+
return int(self.block_number_cache[tx_hash])
|
37
|
+
|
38
|
+
block_number = self.fetch_block_number(tx_hash)
|
39
|
+
self.block_number_cache[tx_hash] = block_number
|
40
|
+
return block_number
|
41
|
+
|
42
|
+
def get_block_timestamp(self, block_number: int) -> int:
|
43
|
+
if block_number in self.block_timestamp_cache:
|
44
|
+
return int(self.block_timestamp_cache[block_number])
|
45
|
+
|
46
|
+
block_timestamp = self.fetch_block_timestamp(block_number)
|
47
|
+
self.block_timestamp_cache[block_number] = block_timestamp
|
48
|
+
return block_timestamp
|
@@ -1,4 +1,3 @@
|
|
1
|
-
import json
|
2
1
|
import os
|
3
2
|
import subprocess
|
4
3
|
from datetime import datetime
|
@@ -6,17 +5,11 @@ from typing import Any, NoReturn, Optional, Type, TypeVar
|
|
6
5
|
|
7
6
|
import pytz
|
8
7
|
import requests
|
9
|
-
from google.cloud import secretmanager
|
10
8
|
from pydantic import BaseModel, ValidationError
|
11
9
|
from scipy.optimize import newton
|
12
10
|
from scipy.stats import entropy
|
13
11
|
|
14
|
-
from prediction_market_agent_tooling.gtypes import
|
15
|
-
DatetimeUTC,
|
16
|
-
PrivateKey,
|
17
|
-
Probability,
|
18
|
-
SecretStr,
|
19
|
-
)
|
12
|
+
from prediction_market_agent_tooling.gtypes import DatetimeUTC, Probability, SecretStr
|
20
13
|
from prediction_market_agent_tooling.loggers import logger
|
21
14
|
from prediction_market_agent_tooling.markets.market_fees import MarketFees
|
22
15
|
|
@@ -214,18 +207,3 @@ def calculate_sell_amount_in_collateral(
|
|
214
207
|
|
215
208
|
amount_to_sell = newton(f, 0)
|
216
209
|
return float(amount_to_sell) * 0.999999 # Avoid rounding errors
|
217
|
-
|
218
|
-
|
219
|
-
def get_private_key_from_gcp_secret(
|
220
|
-
secret_id: str,
|
221
|
-
project_id: str = "582587111398", # Gnosis AI default project_id
|
222
|
-
version_id: str = "latest",
|
223
|
-
) -> PrivateKey:
|
224
|
-
client = secretmanager.SecretManagerServiceClient()
|
225
|
-
name = f"projects/{project_id}/secrets/{secret_id}/versions/{version_id}"
|
226
|
-
response = client.access_secret_version(request={"name": name})
|
227
|
-
secret_payload = response.payload.data.decode("UTF-8")
|
228
|
-
secret_json = json.loads(secret_payload)
|
229
|
-
if "private_key" not in secret_json:
|
230
|
-
raise ValueError(f"Private key not found in gcp secret {secret_id}")
|
231
|
-
return PrivateKey(SecretStr(secret_json["private_key"]))
|
@@ -263,7 +263,11 @@ def send_function_on_contract_tx_using_safe(
|
|
263
263
|
)
|
264
264
|
safe_tx.sign(from_private_key.get_secret_value())
|
265
265
|
safe_tx.call() # simulate call
|
266
|
-
|
266
|
+
eoa_nonce = web3.eth.get_transaction_count(eoa_public_key)
|
267
|
+
tx_hash, tx = safe_tx.execute(
|
268
|
+
from_private_key.get_secret_value(),
|
269
|
+
tx_nonce=eoa_nonce,
|
270
|
+
)
|
267
271
|
receipt_tx = web3.eth.wait_for_transaction_receipt(tx_hash, timeout=timeout)
|
268
272
|
check_tx_receipt(receipt_tx)
|
269
273
|
return receipt_tx
|
@@ -16,8 +16,8 @@ prediction_market_agent_tooling/benchmark/__init__.py,sha256=47DEQpj8HBSa-_TImW-
|
|
16
16
|
prediction_market_agent_tooling/benchmark/agents.py,sha256=B1-uWdyeN4GGKMWGK_-CcAFJg1m9Y_XuaeIHPB29QR8,3971
|
17
17
|
prediction_market_agent_tooling/benchmark/benchmark.py,sha256=MqTiaaJ3cYiOLUVR7OyImLWxcEya3Rl5JyFYW-K0lwM,17097
|
18
18
|
prediction_market_agent_tooling/benchmark/utils.py,sha256=D0MfUkVZllmvcU0VOurk9tcKT7JTtwwOp-63zuCBVuc,2880
|
19
|
-
prediction_market_agent_tooling/config.py,sha256=
|
20
|
-
prediction_market_agent_tooling/deploy/agent.py,sha256=
|
19
|
+
prediction_market_agent_tooling/config.py,sha256=Ffb1ftRiguAxa5cS0nXvKK01HomdqzFDCsp8rFd5taM,7553
|
20
|
+
prediction_market_agent_tooling/deploy/agent.py,sha256=58Ms6wFcRM3yhpdDVT-ohryZhHJNinn1Z4MdrmCMXvM,23627
|
21
21
|
prediction_market_agent_tooling/deploy/agent_example.py,sha256=dIIdZashExWk9tOdyDjw87AuUcGyM7jYxNChYrVK2dM,1001
|
22
22
|
prediction_market_agent_tooling/deploy/betting_strategy.py,sha256=kMrIE3wMv_IB6nJd_1DmDXDkEZhsXFOgyTd7JZ0gqHI,13068
|
23
23
|
prediction_market_agent_tooling/deploy/constants.py,sha256=M5ty8URipYMGe_G-RzxRydK3AFL6CyvmqCraJUrLBnE,82
|
@@ -33,10 +33,10 @@ prediction_market_agent_tooling/loggers.py,sha256=Am6HHXRNO545BO3l7Ue9Wb2TkYE1OK
|
|
33
33
|
prediction_market_agent_tooling/markets/agent_market.py,sha256=W2ME57-CSAhrt8qm8-b5r7yLq-Sk7R_BZMaApvjhrUE,12901
|
34
34
|
prediction_market_agent_tooling/markets/base_subgraph_handler.py,sha256=IxDTwX4tej9j5olNkXcLIE0RCF1Nh2icZQUT2ERMmZo,1937
|
35
35
|
prediction_market_agent_tooling/markets/categorize.py,sha256=jsoHWvZk9pU6n17oWSCcCxNNYVwlb_NXsZxKRI7vmsk,1301
|
36
|
-
prediction_market_agent_tooling/markets/data_models.py,sha256=
|
36
|
+
prediction_market_agent_tooling/markets/data_models.py,sha256=VoEWm338qQMQIRvWpWpDgDjVk9D_3tCHrZPd0Gy0dAA,4033
|
37
37
|
prediction_market_agent_tooling/markets/manifold/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
38
38
|
prediction_market_agent_tooling/markets/manifold/api.py,sha256=Fd0HYnstvvHO6AZkp1xiRlvCwQUc8kLR8DAj6PAZu0s,7297
|
39
|
-
prediction_market_agent_tooling/markets/manifold/data_models.py,sha256=
|
39
|
+
prediction_market_agent_tooling/markets/manifold/data_models.py,sha256=eiGS4rEkxseZNpEb2BICKnjF0qqgkQTMuUPbSe7_04I,6059
|
40
40
|
prediction_market_agent_tooling/markets/manifold/manifold.py,sha256=qemQIwuFg4yf6egGWFp9lWpz1lXr02QiBeZ2akcT6II,5026
|
41
41
|
prediction_market_agent_tooling/markets/manifold/utils.py,sha256=cPPFWXm3vCYH1jy7_ctJZuQH9ZDaPL4_AgAYzGWkoow,513
|
42
42
|
prediction_market_agent_tooling/markets/market_fees.py,sha256=Q64T9uaJx0Vllt0BkrPmpMEz53ra-hMVY8Czi7CEP7s,1227
|
@@ -45,23 +45,24 @@ prediction_market_agent_tooling/markets/metaculus/api.py,sha256=4TRPGytQQbSdf42D
|
|
45
45
|
prediction_market_agent_tooling/markets/metaculus/data_models.py,sha256=Suxa7xELdYuFNKqvGvFh8qyfVtAg79E-vaQ6dqNZOtA,3261
|
46
46
|
prediction_market_agent_tooling/markets/metaculus/metaculus.py,sha256=86TIx6cavEWc8Cv4KpZxSvwiSw9oFybXE3YB49pg-CA,4377
|
47
47
|
prediction_market_agent_tooling/markets/omen/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
48
|
-
prediction_market_agent_tooling/markets/omen/data_models.py,sha256=
|
49
|
-
prediction_market_agent_tooling/markets/omen/omen.py,sha256=
|
50
|
-
prediction_market_agent_tooling/markets/omen/omen_contracts.py,sha256=
|
48
|
+
prediction_market_agent_tooling/markets/omen/data_models.py,sha256=sUiv8xdccvw15ndgbHIavwz7O_eBxp4wGX2zuuZkd2g,27768
|
49
|
+
prediction_market_agent_tooling/markets/omen/omen.py,sha256=6zo8iBBLdI9g9keJ1dw9PXs4rf4V4tCW8D4e08f3g0Q,51349
|
50
|
+
prediction_market_agent_tooling/markets/omen/omen_contracts.py,sha256=baXJwk-jSI3-FV-k239oCNOA4oKz6LT47juX8AKpW3A,28297
|
51
51
|
prediction_market_agent_tooling/markets/omen/omen_resolving.py,sha256=iDWdjICGkt968exwCjY-6nsnQyrrNAg3YjnDdP430GQ,9415
|
52
|
-
prediction_market_agent_tooling/markets/omen/omen_subgraph_handler.py,sha256=
|
52
|
+
prediction_market_agent_tooling/markets/omen/omen_subgraph_handler.py,sha256=lG-2hCmmkjKHX1Ca-SipLBeETnTheXpjg5Qfed0tqFo,36506
|
53
53
|
prediction_market_agent_tooling/markets/polymarket/api.py,sha256=UZ4_TG8ceb9Y-qgsOKs8Qiv8zDt957QkT8IX2c83yqo,4800
|
54
54
|
prediction_market_agent_tooling/markets/polymarket/data_models.py,sha256=Fd5PI5y3mJM8VHExBhWFWEnuuIKxQmIAXgBuoPDvNjw,4341
|
55
55
|
prediction_market_agent_tooling/markets/polymarket/data_models_web.py,sha256=VZhVccTApygSKMmy6Au2G02JCJOKJnR_oVeKlaesuSg,12548
|
56
56
|
prediction_market_agent_tooling/markets/polymarket/polymarket.py,sha256=NRoZK71PtH8kkangMqme7twcAXhRJSSabbmOir-UnAI,3418
|
57
|
-
prediction_market_agent_tooling/markets/polymarket/utils.py,sha256=
|
57
|
+
prediction_market_agent_tooling/markets/polymarket/utils.py,sha256=DImFxeMg8lTfsEDZ8FavndW38TfUsCkawcVGnucsuGo,2029
|
58
58
|
prediction_market_agent_tooling/markets/seer/data_models.py,sha256=2f6DOXhGerYbTSk5vUvw_y87TcUxOtSfca8-Et7imtU,643
|
59
59
|
prediction_market_agent_tooling/markets/seer/seer_subgraph_handler.py,sha256=Jola8AxmNDljBCzl6Gvjb9qH75Y7D5dAwbdZl_jndN8,5478
|
60
|
+
prediction_market_agent_tooling/monitor/financial_metrics/financial_metrics.py,sha256=fEiD-upH7vm5FWSND86r_qW0oV5ZonhaJEBxLK0OZAs,2672
|
60
61
|
prediction_market_agent_tooling/monitor/markets/manifold.py,sha256=TS4ERwTfQnot8dhekNyVNhJYf5ysYsjF-9v5_kM3aVI,3334
|
61
62
|
prediction_market_agent_tooling/monitor/markets/metaculus.py,sha256=LOnyWWBFdg10-cTWdb76nOsNjDloO8OfMT85GBzRCFI,1455
|
62
63
|
prediction_market_agent_tooling/monitor/markets/omen.py,sha256=EqiJYTvDbSu7fBpbrBmCuf3fc6GHr4MxWrBGa69MIyc,3305
|
63
64
|
prediction_market_agent_tooling/monitor/markets/polymarket.py,sha256=wak8o4BYaGbLpshQD12OrsqNABdanyID6ql95lEG2io,1870
|
64
|
-
prediction_market_agent_tooling/monitor/monitor.py,sha256
|
65
|
+
prediction_market_agent_tooling/monitor/monitor.py,sha256=4kMev1iGHQiEFslEqt5bWiXAyM_Qxb4rdMVKx2H9e1U,14235
|
65
66
|
prediction_market_agent_tooling/monitor/monitor_app.py,sha256=zNHSwH_KEiv8aOwvfo1JrNuSFMefpzXPWtellhnJpTI,4775
|
66
67
|
prediction_market_agent_tooling/monitor/monitor_settings.py,sha256=Xiozs3AsufuJ04JOe1vjUri-IAMWHjjmc2ugGGiHNH4,947
|
67
68
|
prediction_market_agent_tooling/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -71,37 +72,39 @@ prediction_market_agent_tooling/tools/betting_strategies/market_moving.py,sha256
|
|
71
72
|
prediction_market_agent_tooling/tools/betting_strategies/minimum_bet_to_win.py,sha256=-FUSuQQgjcWSSnoFxnlAyTeilY6raJABJVM2QKkFqAY,438
|
72
73
|
prediction_market_agent_tooling/tools/betting_strategies/stretch_bet_between.py,sha256=THMXwFlskvzbjnX_OiYtDSzI8XVFyULWfP2525_9UGc,429
|
73
74
|
prediction_market_agent_tooling/tools/betting_strategies/utils.py,sha256=kpIb-ci67Vc1Yqqaa-_S4OUkbhWSIYog4_Iwp69HU_k,97
|
74
|
-
prediction_market_agent_tooling/tools/caches/db_cache.py,sha256=
|
75
|
+
prediction_market_agent_tooling/tools/caches/db_cache.py,sha256=rkA7somZZo5G6OZVvNrCuCVc4kn7TUoPxmOq4J6BZ54,10391
|
75
76
|
prediction_market_agent_tooling/tools/caches/inmemory_cache.py,sha256=tGHHd9HCiE_hCCtPtloHZQdDfBuiow9YsqJNYi2Tx_0,499
|
76
|
-
prediction_market_agent_tooling/tools/
|
77
|
+
prediction_market_agent_tooling/tools/caches/serializers.py,sha256=upSXN5__rmRlzJ6tv1h7FodKzJu9eCkFrN_zeuwroJM,2151
|
78
|
+
prediction_market_agent_tooling/tools/contract.py,sha256=Um_nQlpYJRBy4MnNR1CPKESehVwx_w35LwYX6T6py_0,20837
|
77
79
|
prediction_market_agent_tooling/tools/costs.py,sha256=EaAJ7v9laD4VEV3d8B44M4u3_oEO_H16jRVCdoZ93Uw,954
|
80
|
+
prediction_market_agent_tooling/tools/custom_exceptions.py,sha256=Fh8z1fbwONvP4-j7AmV_PuEcoqb6-QXa9PJ9m7guMcM,93
|
78
81
|
prediction_market_agent_tooling/tools/datetime_utc.py,sha256=2JSWF7AXQnv04_D_cu9Vmdkq0TWmGJ1QcK9AeqrA-U8,2765
|
79
|
-
prediction_market_agent_tooling/tools/
|
80
|
-
prediction_market_agent_tooling/tools/
|
82
|
+
prediction_market_agent_tooling/tools/db/db_manager.py,sha256=-WGYY-ZyqPveXb642gw4-Zh-RicMrBFgx7uqCB8TuDg,2801
|
83
|
+
prediction_market_agent_tooling/tools/google_utils.py,sha256=t3_UEEvKX3L0biSIQ560GdRbllQ6eprhK_upE243A-0,3185
|
81
84
|
prediction_market_agent_tooling/tools/hexbytes_custom.py,sha256=Bp94qgPjvjWf1Vb4lNzGFDXRdThw1rJ91vL6r2PWq5E,2096
|
82
85
|
prediction_market_agent_tooling/tools/httpx_cached_client.py,sha256=0-N1r0zcGKlY9Rk-Ab8hbqwc54eMbsoa3jXL0_yCCiM,355
|
83
86
|
prediction_market_agent_tooling/tools/image_gen/image_gen.py,sha256=HzRwBx62hOXBOmrtpkXaP9Qq1Ku03uUGdREocyjLQ_k,1266
|
84
|
-
prediction_market_agent_tooling/tools/image_gen/market_thumbnail_gen.py,sha256=
|
87
|
+
prediction_market_agent_tooling/tools/image_gen/market_thumbnail_gen.py,sha256=jgOow4zw6g8dIJrog6Tp-3NQs4wjUJ3VgVKyMQv-0QM,1286
|
85
88
|
prediction_market_agent_tooling/tools/ipfs/ipfs_handler.py,sha256=CTTMfTvs_8PH4kAtlQby2aeEKwgpmxtuGbd4oYIdJ2A,1201
|
86
|
-
prediction_market_agent_tooling/tools/is_invalid.py,sha256=
|
87
|
-
prediction_market_agent_tooling/tools/is_predictable.py,sha256=
|
89
|
+
prediction_market_agent_tooling/tools/is_invalid.py,sha256=vuX0TKKhc_7iVnwAjXvfZeFwjr9nyYgREaYQDe-GYgA,5334
|
90
|
+
prediction_market_agent_tooling/tools/is_predictable.py,sha256=dSuL8eLnGNKd_MQ3CaT1OuQkAykr3m5kn7f8HHKgDcM,6797
|
88
91
|
prediction_market_agent_tooling/tools/langfuse_.py,sha256=jI_4ROxqo41CCnWGS1vN_AeDVhRzLMaQLxH3kxDu3L8,1153
|
89
|
-
prediction_market_agent_tooling/tools/langfuse_client_utils.py,sha256=
|
92
|
+
prediction_market_agent_tooling/tools/langfuse_client_utils.py,sha256=_m5SFnJJy4E0ubvY8ohzEEjES4nMJ_2zfa3wp4x3gSA,5817
|
90
93
|
prediction_market_agent_tooling/tools/omen/reality_accuracy.py,sha256=M1SF7iSW1gVlQSTskdVFTn09uPLST23YeipVIWj54io,2236
|
91
94
|
prediction_market_agent_tooling/tools/parallelism.py,sha256=6Gou0hbjtMZrYvxjTDFUDZuxmE2nqZVbb6hkg1hF82A,1022
|
92
|
-
prediction_market_agent_tooling/tools/pickle_utils.py,sha256=PUNRJGdURUnLlzbZoSCiOrikRbEC596hi--Z3q8Wt84,1144
|
93
95
|
prediction_market_agent_tooling/tools/relevant_news_analysis/data_models.py,sha256=95l84aztFaxcRLLcRQ46yKJbIlOEuDAbIGLouyliDzA,1316
|
94
96
|
prediction_market_agent_tooling/tools/relevant_news_analysis/relevant_news_analysis.py,sha256=CddJem7tk15NAudJDwmuL8znTycbR-YI8kTNtd3LzG8,5474
|
95
|
-
prediction_market_agent_tooling/tools/relevant_news_analysis/relevant_news_cache.py,sha256=
|
97
|
+
prediction_market_agent_tooling/tools/relevant_news_analysis/relevant_news_cache.py,sha256=ErLp284YlD7k_M8Si9OT86HuzfmSo1bPlLJtegXx1TA,3011
|
96
98
|
prediction_market_agent_tooling/tools/safe.py,sha256=9vxGGLvSPnfy-sxUFDpBTe8omqpGXP7MzvGPp6bRxrU,5197
|
97
99
|
prediction_market_agent_tooling/tools/singleton.py,sha256=CiIELUiI-OeS7U7eeHEt0rnVhtQGzwoUdAgn_7u_GBM,729
|
98
100
|
prediction_market_agent_tooling/tools/streamlit_user_login.py,sha256=NXEqfjT9Lc9QtliwSGRASIz1opjQ7Btme43H4qJbzgE,3010
|
99
101
|
prediction_market_agent_tooling/tools/tavily/tavily_models.py,sha256=5ldQs1pZe6uJ5eDAuP4OLpzmcqYShlIV67kttNFvGS0,342
|
100
102
|
prediction_market_agent_tooling/tools/tavily/tavily_search.py,sha256=Kw2mXNkMTYTEe1MBSTqhQmLoeXtgb6CkmHlcAJvhtqE,3809
|
101
|
-
prediction_market_agent_tooling/tools/
|
102
|
-
prediction_market_agent_tooling/tools/
|
103
|
-
prediction_market_agent_tooling
|
104
|
-
prediction_market_agent_tooling-0.
|
105
|
-
prediction_market_agent_tooling-0.
|
106
|
-
prediction_market_agent_tooling-0.
|
107
|
-
prediction_market_agent_tooling-0.
|
103
|
+
prediction_market_agent_tooling/tools/transaction_cache.py,sha256=C96OHkNqPJr_yDiHesSRgekeXIbX62qFl9qldArleuo,1800
|
104
|
+
prediction_market_agent_tooling/tools/utils.py,sha256=WvuUCHgMCiMq8_wMm5PHNwvLhcdDk2zGKaAM8OUC-qY,6438
|
105
|
+
prediction_market_agent_tooling/tools/web3_utils.py,sha256=hWDa7D-jP-iW647t0ATPyiUgKbAq25iH97KUnha25SQ,11944
|
106
|
+
prediction_market_agent_tooling-0.57.1.dist-info/LICENSE,sha256=6or154nLLU6bELzjh0mCreFjt0m2v72zLi3yHE0QbeE,7650
|
107
|
+
prediction_market_agent_tooling-0.57.1.dist-info/METADATA,sha256=dOd_dooUIoLkSfsh7mHctHKfDM1W4fCmqu-Xgr_8gAY,8106
|
108
|
+
prediction_market_agent_tooling-0.57.1.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
|
109
|
+
prediction_market_agent_tooling-0.57.1.dist-info/entry_points.txt,sha256=m8PukHbeH5g0IAAmOf_1Ahm-sGAMdhSSRQmwtpmi2s8,81
|
110
|
+
prediction_market_agent_tooling-0.57.1.dist-info/RECORD,,
|
@@ -1,31 +0,0 @@
|
|
1
|
-
import typing as t
|
2
|
-
|
3
|
-
InitialisedValue = t.TypeVar("InitialisedValue")
|
4
|
-
|
5
|
-
|
6
|
-
class InitialiseNonPickable(t.Generic[InitialisedValue]):
|
7
|
-
"""
|
8
|
-
Use this class to wrap values that you want to be shared within a thread,
|
9
|
-
but they are re-initialised for a new processes.
|
10
|
-
|
11
|
-
Initialiser for the value still needs to be pickable.
|
12
|
-
"""
|
13
|
-
|
14
|
-
def __init__(self, initialiser: t.Callable[[], InitialisedValue]) -> None:
|
15
|
-
self.value: InitialisedValue | None = None
|
16
|
-
self.initialiser = initialiser
|
17
|
-
|
18
|
-
def __getstate__(self) -> dict[str, t.Any]:
|
19
|
-
# During pickling, always return `value` as just None, which is pickable and this class will re-initialise it in `get_value` when called.
|
20
|
-
return {"value": None, "initialiser": self.initialiser}
|
21
|
-
|
22
|
-
def __setstate__(self, d: dict[str, t.Any]) -> None:
|
23
|
-
self.value = d["value"]
|
24
|
-
self.initialiser = d["initialiser"]
|
25
|
-
|
26
|
-
def get_value(self) -> InitialisedValue:
|
27
|
-
"""Use this function to get the wrapped value, which will be initialised if necessary."""
|
28
|
-
if self.value is None:
|
29
|
-
self.value = self.initialiser()
|
30
|
-
|
31
|
-
return self.value
|
File without changes
|
File without changes
|