prediction-market-agent-tooling 0.56.0.dev1858__py3-none-any.whl → 0.56.0.dev1860__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/tools/caches/db_cache.py +53 -24
- prediction_market_agent_tooling/tools/is_invalid.py +2 -1
- {prediction_market_agent_tooling-0.56.0.dev1858.dist-info → prediction_market_agent_tooling-0.56.0.dev1860.dist-info}/METADATA +1 -1
- {prediction_market_agent_tooling-0.56.0.dev1858.dist-info → prediction_market_agent_tooling-0.56.0.dev1860.dist-info}/RECORD +7 -7
- {prediction_market_agent_tooling-0.56.0.dev1858.dist-info → prediction_market_agent_tooling-0.56.0.dev1860.dist-info}/LICENSE +0 -0
- {prediction_market_agent_tooling-0.56.0.dev1858.dist-info → prediction_market_agent_tooling-0.56.0.dev1860.dist-info}/WHEEL +0 -0
- {prediction_market_agent_tooling-0.56.0.dev1858.dist-info → prediction_market_agent_tooling-0.56.0.dev1860.dist-info}/entry_points.txt +0 -0
@@ -114,6 +114,7 @@ def db_cache(
|
|
114
114
|
|
115
115
|
@wraps(func)
|
116
116
|
def wrapper(*args: Any, **kwargs: Any) -> Any:
|
117
|
+
# If caching is disabled, just call the function and return it
|
117
118
|
if not api_keys.ENABLE_CACHE:
|
118
119
|
return func(*args, **kwargs)
|
119
120
|
|
@@ -183,11 +184,15 @@ def db_cache(
|
|
183
184
|
|
184
185
|
if cached_result:
|
185
186
|
logger.info(
|
186
|
-
|
187
|
+
# Keep the special [case-hit] identifier so we can easily track it in GCP.
|
188
|
+
f"[cache-hit] Cache hit for {full_function_name} with args {args_dict} and output {cached_result.result}"
|
187
189
|
)
|
188
190
|
if is_pydantic_model:
|
191
|
+
# If the output contains any Pydantic models, we need to initialise them.
|
189
192
|
try:
|
190
|
-
return
|
193
|
+
return convert_return_type_to_pydantic(
|
194
|
+
return_type, cached_result.result
|
195
|
+
)
|
191
196
|
except ValueError as e:
|
192
197
|
# In case of backward-incompatible pydantic model, just treat it as cache miss, to not error out.
|
193
198
|
logger.warning(
|
@@ -199,13 +204,14 @@ def db_cache(
|
|
199
204
|
|
200
205
|
# On cache miss, compute the result
|
201
206
|
computed_result = func(*args, **kwargs)
|
207
|
+
# Keep the special [case-miss] identifier so we can easily track it in GCP.
|
202
208
|
logger.info(
|
203
|
-
f"Cache miss for {full_function_name} with args {args_dict}, computed the output {computed_result}"
|
209
|
+
f"[cache-miss] Cache miss for {full_function_name} with args {args_dict}, computed the output {computed_result}"
|
204
210
|
)
|
205
211
|
|
206
|
-
# If postgres access was specified, save it
|
212
|
+
# If postgres access was specified, save it.
|
207
213
|
if engine is not None and (cache_none or computed_result is not None):
|
208
|
-
#
|
214
|
+
# In case of Pydantic outputs, we need to dictionarize it for it to be serializable.
|
209
215
|
result_data = (
|
210
216
|
convert_pydantic_to_dict(computed_result)
|
211
217
|
if is_pydantic_model
|
@@ -229,18 +235,25 @@ def db_cache(
|
|
229
235
|
return cast(FunctionT, wrapper)
|
230
236
|
|
231
237
|
|
232
|
-
def contains_pydantic_model(
|
233
|
-
|
238
|
+
def contains_pydantic_model(return_type: Any) -> bool:
|
239
|
+
"""
|
240
|
+
Check if the return type contains anything that's a Pydantic model (including nested structures, like `list[BaseModel]`, `dict[str, list[BaseModel]]`, etc.)
|
241
|
+
"""
|
242
|
+
if return_type is None:
|
234
243
|
return False
|
235
|
-
origin = get_origin(
|
244
|
+
origin = get_origin(return_type)
|
236
245
|
if origin is not None:
|
237
|
-
return any(contains_pydantic_model(arg) for arg in get_args(
|
238
|
-
if inspect.isclass(
|
239
|
-
return issubclass(
|
246
|
+
return any(contains_pydantic_model(arg) for arg in get_args(return_type))
|
247
|
+
if inspect.isclass(return_type):
|
248
|
+
return issubclass(return_type, BaseModel)
|
240
249
|
return False
|
241
250
|
|
242
251
|
|
243
|
-
def json_serializer_default_fn(y:
|
252
|
+
def json_serializer_default_fn(y: DatetimeUTC | timedelta | date) -> str:
|
253
|
+
"""
|
254
|
+
Used to serialize objects that don't support it by default into a specific string that can be deserialized out later.
|
255
|
+
If you add something here, also add it to `replace_custom_stringified_objects` below.
|
256
|
+
"""
|
244
257
|
if isinstance(y, DatetimeUTC):
|
245
258
|
return f"DatetimeUTC::{y.isoformat()}"
|
246
259
|
elif isinstance(y, timedelta):
|
@@ -257,6 +270,9 @@ def json_serializer(x: Any) -> str:
|
|
257
270
|
|
258
271
|
|
259
272
|
def replace_custom_stringified_objects(obj: Any) -> Any:
|
273
|
+
"""
|
274
|
+
Used to deserialize objects from `json_serializer_default_fn` into their proper form.
|
275
|
+
"""
|
260
276
|
if isinstance(obj, str):
|
261
277
|
if obj.startswith("DatetimeUTC::"):
|
262
278
|
iso_str = obj[len("DatetimeUTC::") :]
|
@@ -283,6 +299,9 @@ def json_deserializer(s: str) -> Any:
|
|
283
299
|
|
284
300
|
|
285
301
|
def convert_pydantic_to_dict(value: Any) -> Any:
|
302
|
+
"""
|
303
|
+
Convert Pydantic models to dictionaries, including if they are in nested structures.
|
304
|
+
"""
|
286
305
|
if isinstance(value, BaseModel):
|
287
306
|
return value.model_dump()
|
288
307
|
elif isinstance(value, dict):
|
@@ -295,20 +314,25 @@ def convert_pydantic_to_dict(value: Any) -> Any:
|
|
295
314
|
return value
|
296
315
|
|
297
316
|
|
298
|
-
def
|
317
|
+
def convert_return_type_to_pydantic(return_type: Any, data: Any) -> Any:
|
318
|
+
"""
|
319
|
+
Used to initialize Pydantic models from anything cached that was originally a Pydantic model in the output. Including models in nested structures.
|
320
|
+
"""
|
299
321
|
# Get the origin and arguments of the model type
|
300
|
-
origin = get_origin(
|
301
|
-
args = get_args(
|
322
|
+
origin = get_origin(return_type)
|
323
|
+
args = get_args(return_type)
|
302
324
|
|
303
325
|
# Check if the data is a dictionary
|
304
326
|
if isinstance(data, dict):
|
305
327
|
# If the model has no origin, check if it is a subclass of BaseModel
|
306
328
|
if origin is None:
|
307
|
-
if inspect.isclass(
|
329
|
+
if inspect.isclass(return_type) and issubclass(return_type, BaseModel):
|
308
330
|
# Convert the dictionary to a Pydantic model
|
309
|
-
return
|
331
|
+
return return_type(
|
310
332
|
**{
|
311
|
-
k:
|
333
|
+
k: convert_return_type_to_pydantic(
|
334
|
+
getattr(return_type, k, None), v
|
335
|
+
)
|
312
336
|
for k, v in data.items()
|
313
337
|
}
|
314
338
|
)
|
@@ -319,20 +343,25 @@ def convert_to_pydantic(model: Any, data: Any) -> Any:
|
|
319
343
|
elif origin is dict:
|
320
344
|
key_type, value_type = args
|
321
345
|
return {
|
322
|
-
|
346
|
+
convert_return_type_to_pydantic(
|
347
|
+
key_type, k
|
348
|
+
): convert_return_type_to_pydantic(value_type, v)
|
323
349
|
for k, v in data.items()
|
324
350
|
}
|
325
351
|
else:
|
326
352
|
# If the origin is not a dictionary, return the data as is
|
327
353
|
return data
|
328
354
|
# Check if the data is a list
|
329
|
-
elif isinstance(data, list):
|
330
|
-
# If the origin is a list, convert each item
|
331
|
-
if origin
|
355
|
+
elif isinstance(data, (list, tuple)):
|
356
|
+
# If the origin is a list or tuple, convert each item
|
357
|
+
if origin in {list, tuple}:
|
332
358
|
item_type = args[0]
|
333
|
-
|
359
|
+
converted_items = [
|
360
|
+
convert_return_type_to_pydantic(item_type, item) for item in data
|
361
|
+
]
|
362
|
+
return type(data)(converted_items)
|
334
363
|
else:
|
335
|
-
# If the origin is not a list, return the data as is
|
364
|
+
# If the origin is not a list or tuple, return the data as is
|
336
365
|
return data
|
337
366
|
else:
|
338
367
|
# If the data is neither a dictionary nor a list, return it as is
|
@@ -34,9 +34,10 @@ QUESTION_IS_INVALID_PROMPT = """Main signs about an invalid question (sometimes
|
|
34
34
|
- Which could give an incentive only to specific participants to commit an immoral violent action, but are in practice unlikely.
|
35
35
|
- Valid: Will the US be engaged in a military conflict with a UN member state in 2021? (It’s unlikely for the US to declare war in order to win a bet on this market).
|
36
36
|
- Valid: Will Derek Chauvin go to jail for the murder of George Flyod? (It’s unlikely that the jurors would collude to make a wrong verdict in order to win this market).
|
37
|
-
- Questions with relative dates will resolve as invalid. Dates must be stated in absolute terms, not relative depending on the current time.
|
37
|
+
- Questions with relative dates will resolve as invalid. Dates must be stated in absolute terms, not relative depending on the current time. But they can be relative to the even specified in the question itself.
|
38
38
|
- Invalid: Who will be the president of the United States in 6 months? ("in 6 months depends on the current time").
|
39
39
|
- Invalid: In the next 14 days, will Gnosis Chain gain another 1M users? ("in the next 14 days depends on the current time").
|
40
|
+
- Valid: Will GNO price go up 10 days after Gnosis Pay cashback program is annouced? ("10 days after" is relative to the event in the question, so we can determine absolute value).
|
40
41
|
- Questions about moral values and not facts will be resolved as invalid.
|
41
42
|
- Invalid: "Is it ethical to eat meat?".
|
42
43
|
|
@@ -69,7 +69,7 @@ prediction_market_agent_tooling/tools/betting_strategies/market_moving.py,sha256
|
|
69
69
|
prediction_market_agent_tooling/tools/betting_strategies/minimum_bet_to_win.py,sha256=-FUSuQQgjcWSSnoFxnlAyTeilY6raJABJVM2QKkFqAY,438
|
70
70
|
prediction_market_agent_tooling/tools/betting_strategies/stretch_bet_between.py,sha256=THMXwFlskvzbjnX_OiYtDSzI8XVFyULWfP2525_9UGc,429
|
71
71
|
prediction_market_agent_tooling/tools/betting_strategies/utils.py,sha256=kpIb-ci67Vc1Yqqaa-_S4OUkbhWSIYog4_Iwp69HU_k,97
|
72
|
-
prediction_market_agent_tooling/tools/caches/db_cache.py,sha256=
|
72
|
+
prediction_market_agent_tooling/tools/caches/db_cache.py,sha256=QkhtNTs7sjwBhBJpkF_dWO5UZBE8Z1FT03WXskpakQg,13847
|
73
73
|
prediction_market_agent_tooling/tools/caches/inmemory_cache.py,sha256=tGHHd9HCiE_hCCtPtloHZQdDfBuiow9YsqJNYi2Tx_0,499
|
74
74
|
prediction_market_agent_tooling/tools/contract.py,sha256=s3yo8IbXTcvAJcPfLM0_NbgaEsWwLsPmyVnOgyjq_xI,20919
|
75
75
|
prediction_market_agent_tooling/tools/costs.py,sha256=EaAJ7v9laD4VEV3d8B44M4u3_oEO_H16jRVCdoZ93Uw,954
|
@@ -81,7 +81,7 @@ prediction_market_agent_tooling/tools/httpx_cached_client.py,sha256=0-N1r0zcGKlY
|
|
81
81
|
prediction_market_agent_tooling/tools/image_gen/image_gen.py,sha256=HzRwBx62hOXBOmrtpkXaP9Qq1Ku03uUGdREocyjLQ_k,1266
|
82
82
|
prediction_market_agent_tooling/tools/image_gen/market_thumbnail_gen.py,sha256=8A3U2uxsCsOfLjru-6R_PPIAuiKY4qFkWp_GSBPV6-s,1280
|
83
83
|
prediction_market_agent_tooling/tools/ipfs/ipfs_handler.py,sha256=CTTMfTvs_8PH4kAtlQby2aeEKwgpmxtuGbd4oYIdJ2A,1201
|
84
|
-
prediction_market_agent_tooling/tools/is_invalid.py,sha256=
|
84
|
+
prediction_market_agent_tooling/tools/is_invalid.py,sha256=Gp8ASGmqXZGdKKQ4U2ZfQj6bx2Wngb4IExIfV54E4j4,5322
|
85
85
|
prediction_market_agent_tooling/tools/is_predictable.py,sha256=VGkxSoJ8CSLknloOLzm5J4-us7XImYxVzvpsAzxbpCc,6730
|
86
86
|
prediction_market_agent_tooling/tools/langfuse_.py,sha256=jI_4ROxqo41CCnWGS1vN_AeDVhRzLMaQLxH3kxDu3L8,1153
|
87
87
|
prediction_market_agent_tooling/tools/langfuse_client_utils.py,sha256=B0PhAQyviFnVbtOCYMxYmcCn66cu9nbqAOIAZcdgiRI,5771
|
@@ -97,8 +97,8 @@ prediction_market_agent_tooling/tools/tavily/tavily_models.py,sha256=5ldQs1pZe6u
|
|
97
97
|
prediction_market_agent_tooling/tools/tavily/tavily_search.py,sha256=Kw2mXNkMTYTEe1MBSTqhQmLoeXtgb6CkmHlcAJvhtqE,3809
|
98
98
|
prediction_market_agent_tooling/tools/utils.py,sha256=W-9SqeCKd51BYMRhDjYPQ7lfNO_zE9EvYpmu2r5WXGA,7163
|
99
99
|
prediction_market_agent_tooling/tools/web3_utils.py,sha256=44W8siSLNQxeib98bbwAe7V5C609NHNlUuxwuWIRDiY,11838
|
100
|
-
prediction_market_agent_tooling-0.56.0.
|
101
|
-
prediction_market_agent_tooling-0.56.0.
|
102
|
-
prediction_market_agent_tooling-0.56.0.
|
103
|
-
prediction_market_agent_tooling-0.56.0.
|
104
|
-
prediction_market_agent_tooling-0.56.0.
|
100
|
+
prediction_market_agent_tooling-0.56.0.dev1860.dist-info/LICENSE,sha256=6or154nLLU6bELzjh0mCreFjt0m2v72zLi3yHE0QbeE,7650
|
101
|
+
prediction_market_agent_tooling-0.56.0.dev1860.dist-info/METADATA,sha256=D5iUZsQ2RbKbhyVvKEtc9A40BfZTJaJWoEqjLreNF_Q,8114
|
102
|
+
prediction_market_agent_tooling-0.56.0.dev1860.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
|
103
|
+
prediction_market_agent_tooling-0.56.0.dev1860.dist-info/entry_points.txt,sha256=m8PukHbeH5g0IAAmOf_1Ahm-sGAMdhSSRQmwtpmi2s8,81
|
104
|
+
prediction_market_agent_tooling-0.56.0.dev1860.dist-info/RECORD,,
|
File without changes
|
File without changes
|