prediction-market-agent-tooling 0.65.12__tar.gz → 0.66.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.
Files changed (132) hide show
  1. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/PKG-INFO +1 -1
  2. prediction_market_agent_tooling-0.66.0/prediction_market_agent_tooling/abis/agentresultmapping.abi.json +192 -0
  3. prediction_market_agent_tooling-0.66.0/prediction_market_agent_tooling/data_download/langfuse_data_downloader.py +405 -0
  4. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/deploy/agent.py +26 -2
  5. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/markets/agent_market.py +0 -6
  6. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/markets/blockchain_utils.py +29 -13
  7. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/markets/data_models.py +15 -4
  8. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/markets/metaculus/metaculus.py +1 -8
  9. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/markets/omen/data_models.py +43 -13
  10. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/markets/omen/omen.py +5 -1
  11. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/markets/omen/omen_constants.py +5 -0
  12. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/markets/omen/omen_contracts.py +14 -6
  13. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/markets/seer/seer.py +13 -1
  14. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/pyproject.toml +1 -1
  15. prediction_market_agent_tooling-0.65.12/prediction_market_agent_tooling/abis/omen_agentresultmapping.abi.json +0 -171
  16. prediction_market_agent_tooling-0.65.12/prediction_market_agent_tooling/data_download/langfuse_data_downloader.py +0 -268
  17. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/LICENSE +0 -0
  18. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/README.md +0 -0
  19. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/abis/debuggingcontract.abi.json +0 -0
  20. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/abis/depositablewrapper_erc20.abi.json +0 -0
  21. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/abis/erc20.abi.json +0 -0
  22. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/abis/erc4626.abi.json +0 -0
  23. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/abis/erc721.abi.json +0 -0
  24. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/abis/gvp2_settlement.abi.json +0 -0
  25. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/abis/omen_dxdao.abi.json +0 -0
  26. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/abis/omen_fpmm.abi.json +0 -0
  27. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/abis/omen_fpmm_conditionaltokens.abi.json +0 -0
  28. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/abis/omen_fpmm_factory.abi.json +0 -0
  29. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/abis/omen_kleros.abi.json +0 -0
  30. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/abis/omen_oracle.abi.json +0 -0
  31. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/abis/omen_realitio.abi.json +0 -0
  32. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/abis/omen_thumbnailmapping.abi.json +0 -0
  33. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/abis/ownable.abi.json +0 -0
  34. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/abis/ownable_erc721.abi.json +0 -0
  35. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/abis/proxy.abi.json +0 -0
  36. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/abis/seer_gnosis_router.abi.json +0 -0
  37. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/abis/seer_market_factory.abi.json +0 -0
  38. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/abis/swapr_router.abi.json +0 -0
  39. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/benchmark/__init__.py +0 -0
  40. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/benchmark/agents.py +0 -0
  41. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/benchmark/benchmark.py +0 -0
  42. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/benchmark/utils.py +0 -0
  43. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/chains.py +0 -0
  44. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/config.py +0 -0
  45. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/deploy/agent_example.py +0 -0
  46. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/deploy/betting_strategy.py +0 -0
  47. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/deploy/constants.py +0 -0
  48. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/deploy/gcp/deploy.py +0 -0
  49. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/deploy/gcp/kubernetes_models.py +0 -0
  50. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/deploy/gcp/utils.py +0 -0
  51. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/deploy/trade_interval.py +0 -0
  52. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/gtypes.py +0 -0
  53. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/jobs/__init__.py +0 -0
  54. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/jobs/jobs_models.py +0 -0
  55. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/jobs/omen/omen_jobs.py +0 -0
  56. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/loggers.py +0 -0
  57. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/logprobs_parser.py +0 -0
  58. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/markets/base_subgraph_handler.py +0 -0
  59. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/markets/categorize.py +0 -0
  60. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/markets/manifold/__init__.py +0 -0
  61. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/markets/manifold/api.py +0 -0
  62. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/markets/manifold/data_models.py +0 -0
  63. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/markets/manifold/manifold.py +0 -0
  64. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/markets/manifold/utils.py +0 -0
  65. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/markets/market_fees.py +0 -0
  66. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/markets/markets.py +0 -0
  67. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/markets/metaculus/api.py +0 -0
  68. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/markets/metaculus/data_models.py +0 -0
  69. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/markets/omen/__init__.py +0 -0
  70. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/markets/omen/cow_contracts.py +0 -0
  71. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/markets/omen/omen_resolving.py +0 -0
  72. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/markets/omen/omen_subgraph_handler.py +0 -0
  73. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/markets/polymarket/api.py +0 -0
  74. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/markets/polymarket/data_models.py +0 -0
  75. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/markets/polymarket/data_models_web.py +0 -0
  76. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/markets/polymarket/polymarket.py +0 -0
  77. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/markets/polymarket/utils.py +0 -0
  78. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/markets/seer/data_models.py +0 -0
  79. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/markets/seer/exceptions.py +0 -0
  80. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/markets/seer/price_manager.py +0 -0
  81. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/markets/seer/seer_contracts.py +0 -0
  82. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/markets/seer/seer_subgraph_handler.py +0 -0
  83. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/markets/seer/subgraph_data_models.py +0 -0
  84. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/markets/seer/swap_pool_handler.py +0 -0
  85. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/py.typed +0 -0
  86. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/tools/_generic_value.py +0 -0
  87. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/tools/balances.py +0 -0
  88. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/tools/betting_strategies/kelly_criterion.py +0 -0
  89. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/tools/betting_strategies/stretch_bet_between.py +0 -0
  90. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/tools/betting_strategies/utils.py +0 -0
  91. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/tools/caches/db_cache.py +0 -0
  92. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/tools/caches/inmemory_cache.py +0 -0
  93. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/tools/caches/serializers.py +0 -0
  94. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/tools/contract.py +0 -0
  95. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/tools/costs.py +0 -0
  96. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/tools/cow/cow_order.py +0 -0
  97. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/tools/cow/models.py +0 -0
  98. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/tools/custom_exceptions.py +0 -0
  99. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/tools/datetime_utc.py +0 -0
  100. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/tools/db/db_manager.py +0 -0
  101. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/tools/google_utils.py +0 -0
  102. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/tools/hexbytes_custom.py +0 -0
  103. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/tools/httpx_cached_client.py +0 -0
  104. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/tools/image_gen/image_gen.py +0 -0
  105. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/tools/image_gen/market_thumbnail_gen.py +0 -0
  106. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/tools/ipfs/ipfs_handler.py +0 -0
  107. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/tools/is_invalid.py +0 -0
  108. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/tools/is_predictable.py +0 -0
  109. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/tools/langfuse_.py +0 -0
  110. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/tools/langfuse_client_utils.py +0 -0
  111. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/tools/omen/reality_accuracy.py +0 -0
  112. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/tools/omen/sell_positions.py +0 -0
  113. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/tools/parallelism.py +0 -0
  114. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/tools/perplexity/perplexity_client.py +0 -0
  115. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/tools/perplexity/perplexity_models.py +0 -0
  116. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/tools/perplexity/perplexity_search.py +0 -0
  117. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/tools/relevant_news_analysis/data_models.py +0 -0
  118. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/tools/relevant_news_analysis/relevant_news_analysis.py +0 -0
  119. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/tools/relevant_news_analysis/relevant_news_cache.py +0 -0
  120. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/tools/safe.py +0 -0
  121. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/tools/singleton.py +0 -0
  122. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/tools/streamlit_user_login.py +0 -0
  123. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/tools/tavily/tavily_models.py +0 -0
  124. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/tools/tavily/tavily_search.py +0 -0
  125. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/tools/tokens/auto_deposit.py +0 -0
  126. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/tools/tokens/auto_withdraw.py +0 -0
  127. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/tools/tokens/main_token.py +0 -0
  128. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/tools/tokens/token_utils.py +0 -0
  129. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/tools/tokens/usd.py +0 -0
  130. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/tools/transaction_cache.py +0 -0
  131. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/tools/utils.py +0 -0
  132. {prediction_market_agent_tooling-0.65.12 → prediction_market_agent_tooling-0.66.0}/prediction_market_agent_tooling/tools/web3_utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: prediction-market-agent-tooling
3
- Version: 0.65.12
3
+ Version: 0.66.0
4
4
  Summary: Tools to benchmark, deploy and monitor prediction market agents.
5
5
  Author: Gnosis
6
6
  Requires-Python: >=3.10,<3.13
@@ -0,0 +1,192 @@
1
+ [
2
+ {
3
+ "inputs": [
4
+ {
5
+ "internalType": "string",
6
+ "name": "_marketPlatformName",
7
+ "type": "string"
8
+ }
9
+ ],
10
+ "stateMutability": "nonpayable",
11
+ "type": "constructor"
12
+ },
13
+ {
14
+ "anonymous": false,
15
+ "inputs": [
16
+ {
17
+ "indexed": true,
18
+ "internalType": "address",
19
+ "name": "marketAddress",
20
+ "type": "address"
21
+ },
22
+ {
23
+ "indexed": true,
24
+ "internalType": "address",
25
+ "name": "publisherAddress",
26
+ "type": "address"
27
+ },
28
+ {
29
+ "indexed": false,
30
+ "internalType": "string[]",
31
+ "name": "outcomes",
32
+ "type": "string[]"
33
+ },
34
+ {
35
+ "indexed": false,
36
+ "internalType": "uint16[]",
37
+ "name": "estimatedProbabilitiesBps",
38
+ "type": "uint16[]"
39
+ },
40
+ {
41
+ "indexed": false,
42
+ "internalType": "bytes32[]",
43
+ "name": "txHashes",
44
+ "type": "bytes32[]"
45
+ },
46
+ {
47
+ "indexed": false,
48
+ "internalType": "bytes32",
49
+ "name": "ipfsHash",
50
+ "type": "bytes32"
51
+ }
52
+ ],
53
+ "name": "PredictionAdded",
54
+ "type": "event"
55
+ },
56
+ {
57
+ "inputs": [
58
+ { "internalType": "address", "name": "marketAddress", "type": "address" },
59
+ {
60
+ "components": [
61
+ {
62
+ "internalType": "address",
63
+ "name": "marketAddress",
64
+ "type": "address"
65
+ },
66
+ {
67
+ "internalType": "address",
68
+ "name": "publisherAddress",
69
+ "type": "address"
70
+ },
71
+ { "internalType": "bytes32", "name": "ipfsHash", "type": "bytes32" },
72
+ {
73
+ "internalType": "bytes32[]",
74
+ "name": "txHashes",
75
+ "type": "bytes32[]"
76
+ },
77
+ {
78
+ "internalType": "string[]",
79
+ "name": "outcomes",
80
+ "type": "string[]"
81
+ },
82
+ {
83
+ "internalType": "uint16[]",
84
+ "name": "estimatedProbabilitiesBps",
85
+ "type": "uint16[]"
86
+ }
87
+ ],
88
+ "internalType": "struct Prediction",
89
+ "name": "prediction",
90
+ "type": "tuple"
91
+ }
92
+ ],
93
+ "name": "addPrediction",
94
+ "outputs": [],
95
+ "stateMutability": "nonpayable",
96
+ "type": "function"
97
+ },
98
+ {
99
+ "inputs": [
100
+ { "internalType": "address", "name": "marketAddress", "type": "address" },
101
+ { "internalType": "uint256", "name": "index", "type": "uint256" }
102
+ ],
103
+ "name": "getPredictionByIndex",
104
+ "outputs": [
105
+ {
106
+ "components": [
107
+ {
108
+ "internalType": "address",
109
+ "name": "marketAddress",
110
+ "type": "address"
111
+ },
112
+ {
113
+ "internalType": "address",
114
+ "name": "publisherAddress",
115
+ "type": "address"
116
+ },
117
+ { "internalType": "bytes32", "name": "ipfsHash", "type": "bytes32" },
118
+ {
119
+ "internalType": "bytes32[]",
120
+ "name": "txHashes",
121
+ "type": "bytes32[]"
122
+ },
123
+ {
124
+ "internalType": "string[]",
125
+ "name": "outcomes",
126
+ "type": "string[]"
127
+ },
128
+ {
129
+ "internalType": "uint16[]",
130
+ "name": "estimatedProbabilitiesBps",
131
+ "type": "uint16[]"
132
+ }
133
+ ],
134
+ "internalType": "struct Prediction",
135
+ "name": "",
136
+ "type": "tuple"
137
+ }
138
+ ],
139
+ "stateMutability": "view",
140
+ "type": "function"
141
+ },
142
+ {
143
+ "inputs": [
144
+ { "internalType": "address", "name": "marketAddress", "type": "address" }
145
+ ],
146
+ "name": "getPredictions",
147
+ "outputs": [
148
+ {
149
+ "components": [
150
+ {
151
+ "internalType": "address",
152
+ "name": "marketAddress",
153
+ "type": "address"
154
+ },
155
+ {
156
+ "internalType": "address",
157
+ "name": "publisherAddress",
158
+ "type": "address"
159
+ },
160
+ { "internalType": "bytes32", "name": "ipfsHash", "type": "bytes32" },
161
+ {
162
+ "internalType": "bytes32[]",
163
+ "name": "txHashes",
164
+ "type": "bytes32[]"
165
+ },
166
+ {
167
+ "internalType": "string[]",
168
+ "name": "outcomes",
169
+ "type": "string[]"
170
+ },
171
+ {
172
+ "internalType": "uint16[]",
173
+ "name": "estimatedProbabilitiesBps",
174
+ "type": "uint16[]"
175
+ }
176
+ ],
177
+ "internalType": "struct Prediction[]",
178
+ "name": "",
179
+ "type": "tuple[]"
180
+ }
181
+ ],
182
+ "stateMutability": "view",
183
+ "type": "function"
184
+ },
185
+ {
186
+ "inputs": [],
187
+ "name": "marketPlatformName",
188
+ "outputs": [{ "internalType": "string", "name": "", "type": "string" }],
189
+ "stateMutability": "view",
190
+ "type": "function"
191
+ }
192
+ ]
@@ -0,0 +1,405 @@
1
+ import json
2
+ import os
3
+ from concurrent.futures import ThreadPoolExecutor, as_completed
4
+ from datetime import datetime, timedelta
5
+ from pathlib import Path
6
+ from typing import Any
7
+
8
+ import pandas as pd
9
+ import typer
10
+ from langfuse import Langfuse
11
+ from langfuse.client import TraceWithDetails
12
+ from pydantic import BaseModel
13
+
14
+ from prediction_market_agent_tooling.config import APIKeys
15
+ from prediction_market_agent_tooling.gtypes import DatetimeUTC, OutcomeStr, OutcomeToken
16
+ from prediction_market_agent_tooling.loggers import logger
17
+ from prediction_market_agent_tooling.markets.agent_market import AgentMarket
18
+ from prediction_market_agent_tooling.markets.data_models import Resolution
19
+ from prediction_market_agent_tooling.markets.markets import MarketType
20
+ from prediction_market_agent_tooling.markets.omen.omen import OmenAgentMarket
21
+ from prediction_market_agent_tooling.markets.seer.seer import SeerAgentMarket
22
+ from prediction_market_agent_tooling.markets.seer.seer_subgraph_handler import (
23
+ SeerSubgraphHandler,
24
+ )
25
+ from prediction_market_agent_tooling.tools.hexbytes_custom import HexBytes
26
+ from prediction_market_agent_tooling.tools.httpx_cached_client import HttpxCachedClient
27
+ from prediction_market_agent_tooling.tools.langfuse_client_utils import (
28
+ get_traces_for_agent,
29
+ )
30
+
31
+ PREDICTION_STATES = [
32
+ "predict_market",
33
+ "_make_prediction_categorical",
34
+ "make_prediction",
35
+ ]
36
+ REPORT_STATES = ["prepare_report"]
37
+
38
+ TRADE_STATES = ["build_trades"]
39
+
40
+ MARKET_RESOLUTION_PROVIDERS = {
41
+ MarketType.OMEN: lambda market_id: OmenAgentMarket.get_binary_market(market_id),
42
+ MarketType.SEER: lambda market_id: SeerAgentMarket.from_data_model_with_subgraph(
43
+ model=SeerSubgraphHandler().get_market_by_id(HexBytes(market_id)),
44
+ seer_subgraph=SeerSubgraphHandler(),
45
+ must_have_prices=False,
46
+ ),
47
+ }
48
+
49
+
50
+ class TraceResult(BaseModel):
51
+ agent_name: str
52
+ trace_id: str
53
+ market_id: str
54
+ market_type: str
55
+ market_question: str
56
+ market_outcomes: list[str]
57
+ market_outcome_token_pool: dict[OutcomeStr, OutcomeToken] | None
58
+ market_created_time: DatetimeUTC | None
59
+ market_close_time: DatetimeUTC | None
60
+ analysis: str
61
+ prediction_reasoning: str
62
+ prediction_decision: str
63
+ prediction_p_yes: float
64
+ prediction_info_utility: float
65
+ prediction_confidence: float
66
+ market_resolution: str | None
67
+ resolution_is_valid: bool | None
68
+ full_market_json: str | None
69
+ prediction_json: str
70
+ trades: list[dict[str, Any]] | None
71
+
72
+
73
+ def get_langfuse_client() -> Langfuse:
74
+ api_keys = APIKeys()
75
+ return Langfuse(
76
+ secret_key=api_keys.langfuse_secret_key.get_secret_value(),
77
+ public_key=api_keys.langfuse_public_key,
78
+ host=api_keys.langfuse_host,
79
+ httpx_client=HttpxCachedClient().get_client(),
80
+ )
81
+
82
+
83
+ def create_output_file_path(
84
+ agent_name: str,
85
+ date_from: DatetimeUTC,
86
+ date_to: DatetimeUTC,
87
+ output_folder: str,
88
+ ) -> str:
89
+ """Create unique output file path, incrementing version if file exists."""
90
+ Path(output_folder).mkdir(parents=True, exist_ok=True)
91
+
92
+ default_file_name = f"{agent_name}_{date_from.date()}_{date_to.date()}"
93
+ output_file = os.path.join(output_folder, f"{default_file_name}.csv")
94
+
95
+ index = 0
96
+ while os.path.exists(output_file):
97
+ index += 1
98
+ output_file = os.path.join(output_folder, f"{default_file_name}_v{index}.csv")
99
+
100
+ return output_file
101
+
102
+
103
+ def download_data_daily(
104
+ agent_name: str,
105
+ date_from: DatetimeUTC,
106
+ date_to: DatetimeUTC,
107
+ only_resolved: bool,
108
+ output_file: str,
109
+ append_mode: bool = False,
110
+ ) -> tuple[int, int]:
111
+ """Download data for a single day/period and return (traces_downloaded, records_saved)."""
112
+ langfuse_client_for_traces = get_langfuse_client()
113
+
114
+ logger.info(f"Processing data for {date_from.date()} to {date_to.date()}")
115
+
116
+ traces = get_traces_for_agent(
117
+ agent_name=agent_name,
118
+ trace_name="process_market",
119
+ from_timestamp=date_from,
120
+ to_timestamp=date_to,
121
+ has_output=True,
122
+ client=langfuse_client_for_traces,
123
+ tags=["answered"],
124
+ )
125
+
126
+ traces_count = len(traces) if traces else 0
127
+ if not traces:
128
+ logger.info(f"No traces found for {date_from.date()}")
129
+ # If this is the first call and no traces, create empty CSV with header
130
+ if not append_mode:
131
+ df_empty = pd.DataFrame(columns=list(TraceResult.model_fields.keys()))
132
+ df_empty.to_csv(output_file, mode="w", header=True, index=False)
133
+ return 0, 0
134
+
135
+ # Use ThreadPoolExecutor with shared client (thread-safe)
136
+ results = []
137
+ with ThreadPoolExecutor(max_workers=3) as executor:
138
+ # Submit all tasks
139
+ future_to_trace = {
140
+ executor.submit(
141
+ process_trace, trace, only_resolved, langfuse_client_for_traces
142
+ ): trace
143
+ for trace in traces
144
+ }
145
+
146
+ # Collect results as they complete
147
+ for future in as_completed(future_to_trace):
148
+ try:
149
+ result = future.result()
150
+ results.append(result)
151
+ except Exception as e:
152
+ trace = future_to_trace[future]
153
+ logger.exception(f"Error processing trace {trace.id}: {e}")
154
+ results.append(None)
155
+
156
+ successful_results = [r for r in results if r is not None]
157
+ if successful_results:
158
+ results_data = [result.model_dump() for result in successful_results]
159
+ df = pd.DataFrame(results_data)
160
+
161
+ df.to_csv(
162
+ output_file,
163
+ mode="a" if append_mode else "w",
164
+ header=not append_mode,
165
+ index=False,
166
+ )
167
+ logger.info(f"Saved {len(successful_results)} records for {date_from.date()}")
168
+ elif not append_mode:
169
+ df_empty = pd.DataFrame(columns=list(TraceResult.model_fields.keys()))
170
+ df_empty.to_csv(output_file, mode="w", header=True, index=False)
171
+
172
+ return traces_count, len(successful_results)
173
+
174
+
175
+ def download_data(
176
+ agent_name: str,
177
+ date_from: DatetimeUTC,
178
+ date_to: DatetimeUTC,
179
+ only_resolved: bool,
180
+ output_folder: str,
181
+ ) -> None:
182
+ output_file = create_output_file_path(agent_name, date_from, date_to, output_folder)
183
+ total_traces = 0
184
+ total_saved = 0
185
+ daily_stats = []
186
+
187
+ current_date = date_from
188
+ first_call = True
189
+
190
+ while current_date < date_to:
191
+ next_date = DatetimeUTC.from_datetime(current_date + timedelta(days=1))
192
+ if next_date > date_to:
193
+ next_date = date_to
194
+
195
+ traces_downloaded, records_saved = download_data_daily(
196
+ agent_name=agent_name,
197
+ date_from=current_date,
198
+ date_to=next_date,
199
+ only_resolved=only_resolved,
200
+ output_file=output_file,
201
+ append_mode=not first_call,
202
+ )
203
+
204
+ daily_stats.append(
205
+ {
206
+ "date": current_date.date(),
207
+ "traces_downloaded": traces_downloaded,
208
+ "records_saved": records_saved,
209
+ }
210
+ )
211
+
212
+ total_traces += traces_downloaded
213
+ total_saved += records_saved
214
+ first_call = False
215
+ current_date = next_date
216
+
217
+ # Print daily report
218
+ logger.info("=" * 60)
219
+ logger.info("DAILY PROCESSING REPORT")
220
+ logger.info("=" * 60)
221
+ for stats in daily_stats:
222
+ total_traces_downloaded = int(stats["traces_downloaded"]) # type: ignore
223
+ total_records_saved = int(stats["records_saved"]) # type: ignore
224
+ success_rate = (
225
+ (total_records_saved / total_traces_downloaded * 100)
226
+ if total_traces_downloaded > 0
227
+ else 0
228
+ )
229
+ logger.info(
230
+ f"{stats['date']}: {total_traces_downloaded} traces downloaded, {total_records_saved} successfully processed ({success_rate:.1f}%)"
231
+ )
232
+
233
+ logger.info("=" * 60)
234
+ logger.info("OVERALL SUMMARY")
235
+ logger.info("=" * 60)
236
+ overall_success_rate = (total_saved / total_traces * 100) if total_traces > 0 else 0
237
+ logger.info(f"Total traces downloaded: {total_traces}")
238
+ logger.info(f"Total records saved: {total_saved}")
239
+ logger.info(f"Overall success rate: {overall_success_rate:.1f}%")
240
+
241
+ if total_saved == 0:
242
+ logger.warning("No results to save")
243
+ else:
244
+ logger.info(f"Output file: {output_file}")
245
+ logger.info("=" * 60)
246
+
247
+
248
+ def process_trace(
249
+ trace: TraceWithDetails,
250
+ only_resolved: bool,
251
+ langfuse_client: Langfuse,
252
+ include_market: bool = True,
253
+ ) -> TraceResult | None:
254
+ try:
255
+ logger.info(f"Processing trace {trace.id}")
256
+ observations = langfuse_client.fetch_observations(trace_id=trace.id)
257
+ logger.info(f"Observations downloaded for trace {trace.id}")
258
+ market_state, market_type = get_agent_market_state(trace.input)
259
+
260
+ prepare_report_obs = [
261
+ obs for obs in observations.data if obs.name in REPORT_STATES
262
+ ]
263
+ predict_market_obs = [
264
+ obs for obs in observations.data if obs.name in PREDICTION_STATES
265
+ ]
266
+ build_trades_obs = [
267
+ obs for obs in observations.data if obs.name in TRADE_STATES
268
+ ]
269
+ if not prepare_report_obs or not predict_market_obs:
270
+ raise ValueError(f"Missing required observations for trace {trace.id}")
271
+
272
+ analysis = prepare_report_obs[0].output
273
+ prediction = predict_market_obs[0].output
274
+
275
+ resolution = get_market_resolution(market_state.id, market_type)
276
+
277
+ if only_resolved and not resolution:
278
+ raise ValueError(f"No resolution found for market {market_state.id}")
279
+
280
+ result = TraceResult(
281
+ agent_name=trace.metadata["agent_class"],
282
+ trace_id=trace.id,
283
+ market_id=market_state.id,
284
+ market_type=market_type.value,
285
+ market_question=market_state.question,
286
+ market_outcomes=list(market_state.outcomes),
287
+ market_outcome_token_pool=market_state.outcome_token_pool,
288
+ market_created_time=market_state.created_time,
289
+ market_close_time=market_state.close_time,
290
+ analysis=analysis,
291
+ prediction_reasoning=prediction["reasoning"],
292
+ prediction_decision="y" if prediction["p_yes"] > 0.5 else "n",
293
+ prediction_p_yes=prediction["p_yes"],
294
+ prediction_info_utility=prediction["info_utility"],
295
+ prediction_confidence=prediction["confidence"],
296
+ prediction_json=json.dumps(prediction),
297
+ market_resolution=resolution.outcome if resolution else None,
298
+ resolution_is_valid=not resolution.invalid if resolution else None,
299
+ full_market_json=market_state.model_dump_json() if include_market else None,
300
+ trades=build_trades_obs[0].output if build_trades_obs else None,
301
+ )
302
+ logger.info(f"Downloaded trace {trace.id} finished")
303
+ return result
304
+
305
+ except Exception as e:
306
+ logger.exception(f"Error processing trace {trace.id}: {e}")
307
+ return None
308
+
309
+
310
+ def get_agent_market_state(
311
+ input_data: dict[str, Any]
312
+ ) -> tuple[AgentMarket, MarketType]:
313
+ if not input_data or "args" not in input_data:
314
+ raise ValueError("Invalid input data: missing args")
315
+
316
+ args = input_data["args"]
317
+ if len(args) < 2:
318
+ raise ValueError("Invalid args: expected at least 2 elements")
319
+
320
+ market_type = MarketType(args[0])
321
+ if market_type not in MARKET_RESOLUTION_PROVIDERS:
322
+ raise ValueError(f"Unknown market type: {market_type}")
323
+
324
+ market_data = args[1] # market object data
325
+
326
+ # recreate probabilities if not present
327
+ if "outcome_token_pool" in market_data and "probabilities" not in market_data:
328
+ market_data["probabilities"] = AgentMarket.build_probability_map(
329
+ [
330
+ OutcomeToken(
331
+ float(value["value"]) if isinstance(value, dict) else float(value)
332
+ ).as_outcome_wei
333
+ for value in market_data["outcome_token_pool"].values()
334
+ ],
335
+ list(market_data["outcome_token_pool"].keys()),
336
+ )
337
+
338
+ if market_type == MarketType.OMEN:
339
+ return OmenAgentMarket.model_validate(market_data), market_type
340
+ elif market_type == MarketType.SEER:
341
+ return SeerAgentMarket.model_validate(market_data), market_type
342
+ else:
343
+ return AgentMarket.model_validate(market_data), market_type
344
+
345
+
346
+ def get_market_resolution(market_id: str, market_type: MarketType) -> Resolution:
347
+ if market_type not in MARKET_RESOLUTION_PROVIDERS:
348
+ raise ValueError(f"Unknown market type: {market_type.market_class}")
349
+
350
+ try:
351
+ market: AgentMarket | None = MARKET_RESOLUTION_PROVIDERS[market_type](market_id)
352
+
353
+ if not market or not market.resolution:
354
+ raise ValueError(f"No resolution found for market: {market_id}")
355
+
356
+ return market.resolution
357
+
358
+ except Exception as e:
359
+ raise ValueError(
360
+ f"Failed to fetch {market_type.market_class} market {market_id} resolution: {e}"
361
+ ) from e
362
+
363
+
364
+ def parse_date(date_str: str, param_name: str) -> DatetimeUTC:
365
+ try:
366
+ return DatetimeUTC.to_datetime_utc(date_str)
367
+ except ValueError as e:
368
+ typer.echo(f"Error: Invalid date format for {param_name}: {date_str}")
369
+ typer.echo("Expected format: YYYY-MM-DD or YYYY-MM-DDTHH:MM:SS")
370
+ raise typer.Exit(1) from e
371
+
372
+
373
+ def main(
374
+ agent_name: str = "DeployablePredictionProphet",
375
+ only_resolved: bool = True,
376
+ date_from: str = typer.Option(
377
+ None, help="Start date in ISO format (YYYY-MM-DD or YYYY-MM-DDTHH:MM:SS)"
378
+ ),
379
+ date_to: str = typer.Option(
380
+ None, help="End date in ISO format (YYYY-MM-DD or YYYY-MM-DDTHH:MM:SS)"
381
+ ),
382
+ output_folder: str = "./agent_trades_output/",
383
+ ) -> None:
384
+ date_from_dt = (
385
+ parse_date(date_from, "date_from")
386
+ if date_from
387
+ else DatetimeUTC.from_datetime(datetime.now() - timedelta(days=1))
388
+ )
389
+ date_to_dt = (
390
+ parse_date(date_to, "date_to")
391
+ if date_to
392
+ else DatetimeUTC.from_datetime(datetime.now())
393
+ )
394
+
395
+ download_data(
396
+ agent_name=agent_name,
397
+ date_from=date_from_dt,
398
+ date_to=date_to_dt,
399
+ only_resolved=only_resolved,
400
+ output_folder=output_folder,
401
+ )
402
+
403
+
404
+ if __name__ == "__main__":
405
+ typer.run(main)
@@ -373,7 +373,8 @@ class DeployablePredictionAgent(DeployableAgent):
373
373
  binary_answer = self.answer_binary_market(market)
374
374
  return (
375
375
  CategoricalProbabilisticAnswer.from_probabilistic_answer(
376
- binary_answer
376
+ binary_answer,
377
+ market.outcomes,
377
378
  )
378
379
  if binary_answer is not None
379
380
  else None
@@ -385,6 +386,27 @@ class DeployablePredictionAgent(DeployableAgent):
385
386
 
386
387
  return self.answer_categorical_market(market)
387
388
 
389
+ def verify_answer_outcomes(
390
+ self, market: AgentMarket, answer: CategoricalProbabilisticAnswer
391
+ ) -> None:
392
+ outcomes_from_prob_map = list(answer.probabilities.keys())
393
+
394
+ if any(
395
+ outcome_from_answer not in market.outcomes
396
+ for outcome_from_answer in outcomes_from_prob_map
397
+ ):
398
+ raise ValueError(
399
+ f"Some of generated outcomes ({outcomes_from_prob_map=}) in probability map doesn't match with market's outcomes ({market.outcomes=})."
400
+ )
401
+
402
+ if any(
403
+ market_outcome not in outcomes_from_prob_map
404
+ for market_outcome in market.outcomes
405
+ ):
406
+ logger.warning(
407
+ f"Some of market's outcomes ({market.outcomes=}) isn't included in the probability map ({outcomes_from_prob_map=})."
408
+ )
409
+
388
410
  def process_market(
389
411
  self,
390
412
  market_type: MarketType,
@@ -399,6 +421,8 @@ class DeployablePredictionAgent(DeployableAgent):
399
421
  answer = self.build_answer(
400
422
  market=market, market_type=market_type, verify_market=verify_market
401
423
  )
424
+ if answer is not None:
425
+ self.verify_answer_outcomes(market=market, answer=answer)
402
426
 
403
427
  processed_market = (
404
428
  ProcessedMarket(answer=answer) if answer is not None else None
@@ -406,7 +430,7 @@ class DeployablePredictionAgent(DeployableAgent):
406
430
 
407
431
  self.update_langfuse_trace_by_processed_market(market_type, processed_market)
408
432
  logger.info(
409
- f"Processed market {market.question=} from {market.url=} with {answer=}."
433
+ f"Processed market {market.question=} from {market.url=} with {processed_market=}."
410
434
  )
411
435
  return processed_market
412
436
 
@@ -21,7 +21,6 @@ from prediction_market_agent_tooling.gtypes import (
21
21
  OutcomeWei,
22
22
  Probability,
23
23
  )
24
- from prediction_market_agent_tooling.loggers import logger
25
24
  from prediction_market_agent_tooling.markets.data_models import (
26
25
  USD,
27
26
  Bet,
@@ -93,11 +92,6 @@ class AgentMarket(BaseModel):
93
92
  outcomes: t.Sequence[OutcomeStr] = check_not_none(info.data.get("outcomes"))
94
93
  if set(probs.keys()) != set(outcomes):
95
94
  raise ValueError("Keys of `probabilities` must match `outcomes` exactly.")
96
- total = float(sum(probs.values()))
97
- if not 0.999 <= total <= 1.001:
98
- # We simply log a warning because for some use-cases (e.g. existing positions), the
99
- # markets might be already closed hence no reliable outcome token prices exist anymore.
100
- logger.warning(f"Probabilities for market {info.data=} do not sum to 1.")
101
95
  return probs
102
96
 
103
97
  @field_validator("outcome_token_pool")