dojozero 0.3.0__tar.gz → 0.5.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.
- {dojozero-0.3.0 → dojozero-0.5.0}/PKG-INFO +4 -2
- {dojozero-0.3.0 → dojozero-0.5.0}/pyproject.toml +5 -2
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/agents/_config.py +16 -4
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/arena_server/_cache.py +18 -3
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/arena_server/_config.py +6 -1
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/arena_server/_endpoints.py +95 -5
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/arena_server/_models.py +15 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/arena_server/_server.py +10 -3
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/arena_server/_utils.py +397 -99
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/betting/__init__.py +32 -17
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/betting/_agent.py +105 -62
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/betting/_broker.py +130 -27
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/betting/_config.py +53 -13
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/betting/_metadata.py +6 -1
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/betting/_models.py +203 -8
- dojozero-0.5.0/src/dojozero/betting/_prediction_broker.py +1225 -0
- dojozero-0.5.0/src/dojozero/betting/_protocol.py +90 -0
- dojozero-0.5.0/src/dojozero/betting/_scoring.py +94 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/cli.py +98 -26
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/core/_models.py +7 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/core/_tracing.py +203 -7
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/dashboard_server/_game_discovery.py +188 -5
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/dashboard_server/_scheduler.py +74 -6
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/dashboard_server/_server.py +260 -18
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/dashboard_server/_trial_manager.py +120 -54
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/data/__init__.py +13 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/data/_models.py +7 -1
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/data/_sls_source.py +11 -1
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/data/polymarket/_api.py +214 -8
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/data/polymarket/_store.py +28 -29
- dojozero-0.5.0/src/dojozero/data/world_cup/__init__.py +37 -0
- dojozero-0.5.0/src/dojozero/data/world_cup/_api.py +100 -0
- dojozero-0.5.0/src/dojozero/data/world_cup/_constants.py +45 -0
- dojozero-0.5.0/src/dojozero/data/world_cup/_events.py +162 -0
- dojozero-0.5.0/src/dojozero/data/world_cup/_factory.py +52 -0
- dojozero-0.5.0/src/dojozero/data/world_cup/_state_tracker.py +164 -0
- dojozero-0.5.0/src/dojozero/data/world_cup/_store.py +776 -0
- dojozero-0.5.0/src/dojozero/data/world_cup/_utils.py +209 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/gateway/__init__.py +12 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/gateway/_adapter.py +274 -69
- dojozero-0.5.0/src/dojozero/gateway/_agentid.py +182 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/gateway/_auth.py +20 -7
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/gateway/_models.py +94 -4
- dojozero-0.5.0/src/dojozero/gateway/_server.py +908 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/nba/_trial.py +14 -2
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/ncaa/_trial.py +14 -1
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/nfl/_trial.py +14 -2
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/sync_service/_redis_client.py +32 -1
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/sync_service/_sync.py +103 -38
- dojozero-0.5.0/src/dojozero/world_cup/__init__.py +8 -0
- dojozero-0.5.0/src/dojozero/world_cup/_agent.py +60 -0
- dojozero-0.5.0/src/dojozero/world_cup/_datastream.py +114 -0
- dojozero-0.5.0/src/dojozero/world_cup/_formatters.py +190 -0
- dojozero-0.5.0/src/dojozero/world_cup/_trial.py +475 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/tests/conftest.py +19 -0
- dojozero-0.5.0/tests/fixtures/world_cup/cwc_2025/plays_735949_aet.json +1 -0
- dojozero-0.5.0/tests/fixtures/world_cup/cwc_2025/plays_735958_final.json +1 -0
- dojozero-0.5.0/tests/fixtures/world_cup/cwc_2025/scoreboard_20250713.json +1 -0
- dojozero-0.5.0/tests/fixtures/world_cup/cwc_2025/summary_735949_aet.json +1 -0
- dojozero-0.5.0/tests/fixtures/world_cup/cwc_2025/summary_735958_final.json +1 -0
- dojozero-0.5.0/tests/fixtures/world_cup/plays_684665.json +1 -0
- dojozero-0.5.0/tests/fixtures/world_cup/scoreboard_conmebol_20250909.json +1 -0
- dojozero-0.5.0/tests/fixtures/world_cup/scoreboard_fifa_world.json +1 -0
- dojozero-0.5.0/tests/fixtures/world_cup/summary_684665.json +1 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/tests/test_agent_configs.py +14 -0
- dojozero-0.5.0/tests/test_arena_cache.py +26 -0
- dojozero-0.5.0/tests/test_arena_landing.py +46 -0
- dojozero-0.5.0/tests/test_arena_leaderboard_cache_sort.py +95 -0
- dojozero-0.5.0/tests/test_arena_leaderboard_prediction.py +289 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/tests/test_arena_replay_seek.py +18 -0
- dojozero-0.5.0/tests/test_arena_stats_prediction.py +104 -0
- dojozero-0.5.0/tests/test_backtest_launch.py +91 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/tests/test_broker.py +254 -2
- dojozero-0.5.0/tests/test_cli_sls_polling.py +323 -0
- dojozero-0.5.0/tests/test_dashboard_agentid.py +110 -0
- dojozero-0.5.0/tests/test_dashboard_games_endpoint.py +79 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/tests/test_data_polymarket.py +208 -1
- dojozero-0.5.0/tests/test_data_world_cup.py +689 -0
- dojozero-0.5.0/tests/test_detect_contest_kind.py +49 -0
- dojozero-0.5.0/tests/test_dual_mode_trial.py +574 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/tests/test_gateway.py +118 -15
- dojozero-0.5.0/tests/test_gateway_agentid.py +399 -0
- dojozero-0.5.0/tests/test_genai_tracing.py +196 -0
- dojozero-0.5.0/tests/test_materialization_tracker.py +306 -0
- dojozero-0.5.0/tests/test_prediction_broker.py +780 -0
- dojozero-0.5.0/tests/test_scoring.py +227 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/tests/test_sls_source.py +91 -1
- dojozero-0.5.0/tests/test_sls_trace_reader_progress.py +302 -0
- dojozero-0.5.0/tests/test_sync_service_period_league_lookback.py +114 -0
- dojozero-0.5.0/tests/test_sync_service_world_cup_games.py +169 -0
- dojozero-0.5.0/tests/test_upcoming_games_from_schedules.py +149 -0
- dojozero-0.5.0/tests/test_world_cup_agent.py +38 -0
- dojozero-0.5.0/tests/test_world_cup_formatters.py +255 -0
- dojozero-0.5.0/tests/test_world_cup_scheduling.py +535 -0
- dojozero-0.5.0/tests/test_world_cup_trial.py +381 -0
- dojozero-0.3.0/src/dojozero/gateway/_server.py +0 -664
- {dojozero-0.3.0 → dojozero-0.5.0}/.gitignore +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/README.md +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/__init__.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/_optional_alicloud.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/agents/__init__.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/agents/_social_board.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/agents/_toolkit.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/agents/_trial_utils.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/arena_server/__init__.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/arena_server/_constants.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/arena_server/_redis_reader.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/arena_server/get_snapshot.sh +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/betting/_formatters.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/core/__init__.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/core/_actors.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/core/_base.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/core/_credentials.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/core/_filesystem_orchestrator_store.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/core/_metadata.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/core/_registry.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/core/_runtime.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/core/_trial_orchestrator.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/core/_types.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/dashboard_server/__init__.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/dashboard_server/_cluster.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/dashboard_server/_gateway_routing.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/dashboard_server/_jsonl_utils.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/dashboard_server/_types.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/data/_backtest.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/data/_config.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/data/_context.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/data/_factory.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/data/_game_info.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/data/_hub.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/data/_processors.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/data/_stores.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/data/_streams.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/data/_subscriptions.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/data/_utils.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/data/espn/__init__.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/data/espn/_api.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/data/espn/_state_tracker.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/data/espn/_stats_events.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/data/espn/_stats_fetcher.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/data/espn/_utils.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/data/nba/__init__.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/data/nba/_api.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/data/nba/_events.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/data/nba/_factory.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/data/nba/_state_tracker.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/data/nba/_store.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/data/nba/_utils.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/data/ncaa/__init__.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/data/ncaa/_api.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/data/ncaa/_events.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/data/ncaa/_factory.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/data/ncaa/_state_tracker.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/data/ncaa/_store.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/data/ncaa/_utils.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/data/nfl/__init__.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/data/nfl/_api.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/data/nfl/_events.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/data/nfl/_factory.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/data/nfl/_state_tracker.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/data/nfl/_store.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/data/nfl/_utils.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/data/polymarket/__init__.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/data/polymarket/_events.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/data/polymarket/_factory.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/data/polymarket/_models.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/data/socialmedia/__init__.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/data/socialmedia/_api.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/data/socialmedia/_events.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/data/socialmedia/_factory.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/data/socialmedia/_formatters.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/data/socialmedia/_store.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/data/socialmedia/_watchlist.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/data/websearch/__init__.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/data/websearch/_api.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/data/websearch/_events.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/data/websearch/_factory.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/data/websearch/_formatters.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/data/websearch/_store.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/gateway/_rate_limit.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/gateway/_sse.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/nba/__init__.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/nba/_agent.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/nba/_datastream.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/nba/_formatters.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/ncaa/__init__.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/ncaa/_agent.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/ncaa/_datastream.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/ncaa/_formatters.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/nfl/__init__.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/nfl/_agent.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/nfl/_datastream.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/nfl/_formatters.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/ray_runtime/__init__.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/ray_runtime/_impl.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/sync_service/__init__.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/sync_service/main.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/utils/__init__.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/utils/oss.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/src/dojozero/utils/time.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/tests/test_agent_event_throttle.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/tests/test_arena_event_deserialization.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/tests/test_arena_span_grouping.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/tests/test_backtest_cache_naming.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/tests/test_betting_formatters.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/tests/test_cli_agents.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/tests/test_cli_dev_span_start.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/tests/test_cluster.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/tests/test_dashboard.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/tests/test_data_hub.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/tests/test_data_nba.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/tests/test_data_nfl.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/tests/test_game_state_tracker.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/tests/test_metadata.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/tests/test_nba_formatters.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/tests/test_nba_moneyline_agent.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/tests/test_nfl_formatters.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/tests/test_nfl_moneyline_agent.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/tests/test_oss.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/tests/test_registry.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/tests/test_scheduler.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/tests/test_social_board.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/tests/test_socialmedia_events.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/tests/test_span_models.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/tests/test_stats_insight_events.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/tests/test_subscriptions.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/tests/test_websearch_events.py +0 -0
- {dojozero-0.3.0 → dojozero-0.5.0}/tests/test_websearch_formatters.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dojozero
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.5.0
|
|
4
4
|
Summary: A platform for running AI agents on realtime sport data and make predictions about game outcomes.
|
|
5
5
|
Project-URL: Homepage, https://github.com/agentscope-ai/DojoZero
|
|
6
6
|
Project-URL: Repository, https://github.com/agentscope-ai/DojoZero
|
|
@@ -16,7 +16,7 @@ Classifier: Programming Language :: Python :: 3.12
|
|
|
16
16
|
Classifier: Programming Language :: Python :: 3.13
|
|
17
17
|
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
18
18
|
Requires-Python: >=3.11
|
|
19
|
-
Requires-Dist: agentscope[gemini]
|
|
19
|
+
Requires-Dist: agentscope[gemini]<2,>=1.0.14
|
|
20
20
|
Requires-Dist: aiohttp>=3.9.0
|
|
21
21
|
Requires-Dist: dashscope>=1.0.0
|
|
22
22
|
Requires-Dist: fastapi>=0.128.0
|
|
@@ -32,6 +32,8 @@ Requires-Dist: pyyaml>=6.0
|
|
|
32
32
|
Requires-Dist: tavily-python>=0.7.12
|
|
33
33
|
Requires-Dist: uvicorn>=0.40.0
|
|
34
34
|
Requires-Dist: xdk>=0.9.0
|
|
35
|
+
Provides-Extra: agentid
|
|
36
|
+
Requires-Dist: agent-id-service-sdk>=0.3.0; extra == 'agentid'
|
|
35
37
|
Provides-Extra: alicloud
|
|
36
38
|
Requires-Dist: alibabacloud-credentials>=1.0.0; extra == 'alicloud'
|
|
37
39
|
Requires-Dist: aliyun-log-python-sdk; extra == 'alicloud'
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "dojozero"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.5.0"
|
|
8
8
|
description = "A platform for running AI agents on realtime sport data and make predictions about game outcomes."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.11"
|
|
@@ -26,7 +26,7 @@ dependencies = [
|
|
|
26
26
|
"PyYAML>=6.0",
|
|
27
27
|
"pydantic>=2.12.4",
|
|
28
28
|
"aiohttp>=3.9.0",
|
|
29
|
-
"agentscope[gemini]>=1.0.14",
|
|
29
|
+
"agentscope[gemini]>=1.0.14,<2",
|
|
30
30
|
"py-clob-client>=0.1.0",
|
|
31
31
|
"fastapi>=0.128.0",
|
|
32
32
|
"uvicorn>=0.40.0",
|
|
@@ -61,3 +61,6 @@ alicloud = [
|
|
|
61
61
|
redis = [
|
|
62
62
|
"redis>=7.2.1",
|
|
63
63
|
]
|
|
64
|
+
agentid = [
|
|
65
|
+
"agent-id-service-sdk>=0.3.0",
|
|
66
|
+
]
|
|
@@ -122,8 +122,14 @@ def load_persona_config(config_path: str | Path) -> PersonaConfig:
|
|
|
122
122
|
Parsed PersonaConfig dictionary
|
|
123
123
|
"""
|
|
124
124
|
path = Path(config_path)
|
|
125
|
-
|
|
126
|
-
|
|
125
|
+
try:
|
|
126
|
+
with path.open("r", encoding="utf-8") as f:
|
|
127
|
+
data: dict[str, Any] = yaml.safe_load(f)
|
|
128
|
+
except FileNotFoundError as e:
|
|
129
|
+
raise FileNotFoundError(
|
|
130
|
+
f"Persona config file not found: {path}. Check the persona_config_path "
|
|
131
|
+
"referenced by your agent or trial-source config."
|
|
132
|
+
) from e
|
|
127
133
|
|
|
128
134
|
return PersonaConfig(sys_prompt=data.get("sys_prompt", ""))
|
|
129
135
|
|
|
@@ -156,8 +162,14 @@ def load_llm_file_config(config_path: str | Path) -> LLMFileConfig:
|
|
|
156
162
|
Parsed LLMFileConfig dictionary with llm as a list of LLMConfig
|
|
157
163
|
"""
|
|
158
164
|
path = Path(config_path)
|
|
159
|
-
|
|
160
|
-
|
|
165
|
+
try:
|
|
166
|
+
with path.open("r", encoding="utf-8") as f:
|
|
167
|
+
data: dict[str, Any] = yaml.safe_load(f)
|
|
168
|
+
except FileNotFoundError as e:
|
|
169
|
+
raise FileNotFoundError(
|
|
170
|
+
f"LLM config file not found: {path}. Check the llm_config_path "
|
|
171
|
+
"referenced by your agent or trial-source config."
|
|
172
|
+
) from e
|
|
161
173
|
|
|
162
174
|
llm_configs: list[LLMConfig] = []
|
|
163
175
|
|
|
@@ -40,7 +40,21 @@ class CacheConfig:
|
|
|
40
40
|
trials_limit: int = 500
|
|
41
41
|
|
|
42
42
|
# Time range
|
|
43
|
-
trials_lookback_days: int =
|
|
43
|
+
trials_lookback_days: int = 365
|
|
44
|
+
# Per-league lookback override (in days). League name uppercase.
|
|
45
|
+
# Used to filter per-league cached views (leaderboard/games/stats/agent_actions).
|
|
46
|
+
# May exceed trials_lookback_days: the SLS fetch window auto-expands to
|
|
47
|
+
# max(trials_lookback_days, max(league_lookback_days.values())) in _sync, so a
|
|
48
|
+
# larger per-league window is still fully covered.
|
|
49
|
+
league_lookback_days: dict[str, int] = field(
|
|
50
|
+
default_factory=lambda: {"NBA": 90, "NFL": 365}
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
def get_league_lookback(self, league: str | None) -> int:
|
|
54
|
+
"""Effective lookback (days) for a given league. Falls back to global."""
|
|
55
|
+
if league is None:
|
|
56
|
+
return self.trials_lookback_days
|
|
57
|
+
return self.league_lookback_days.get(league.upper(), self.trials_lookback_days)
|
|
44
58
|
|
|
45
59
|
@classmethod
|
|
46
60
|
def from_arena_config(cls, config: "ArenaServerConfig") -> "CacheConfig":
|
|
@@ -55,6 +69,7 @@ class CacheConfig:
|
|
|
55
69
|
leaderboard_limit=config.query_limits.leaderboard_limit,
|
|
56
70
|
trials_limit=config.cache.trials_limit,
|
|
57
71
|
trials_lookback_days=config.cache.trials_lookback_days,
|
|
72
|
+
league_lookback_days=dict(config.cache.league_lookback_days),
|
|
58
73
|
)
|
|
59
74
|
|
|
60
75
|
|
|
@@ -62,7 +77,7 @@ class CacheConfig:
|
|
|
62
77
|
from dojozero.arena_server._config import ArenaServerConfig # noqa: E402
|
|
63
78
|
|
|
64
79
|
DEFAULT_CACHE_CONFIG = CacheConfig()
|
|
65
|
-
CACHEABLE_LEAGUES: frozenset[str] = frozenset({"NBA", "NFL"})
|
|
80
|
+
CACHEABLE_LEAGUES: frozenset[str] = frozenset({"NBA", "NFL", "WORLD_CUP"})
|
|
66
81
|
LEADERBOARD_PERIODS: tuple[str, ...] = ("7d", "14d", "30d")
|
|
67
82
|
|
|
68
83
|
|
|
@@ -102,7 +117,7 @@ class LandingPageCache:
|
|
|
102
117
|
- leaderboard: Agent rankings (global + per-league)
|
|
103
118
|
- agent_actions: Recent agent actions (global + per-league)
|
|
104
119
|
|
|
105
|
-
Per-league caches are maintained for CACHEABLE_LEAGUES
|
|
120
|
+
Per-league caches are maintained for CACHEABLE_LEAGUES.
|
|
106
121
|
|
|
107
122
|
Note: No lock is needed because BackgroundRefresher is the single writer
|
|
108
123
|
and Python's GIL ensures atomic reference assignments.
|
|
@@ -20,7 +20,12 @@ class CacheConfig(BaseModel):
|
|
|
20
20
|
|
|
21
21
|
# Time range
|
|
22
22
|
trials_lookback_days: int = Field(
|
|
23
|
-
default=
|
|
23
|
+
default=365,
|
|
24
|
+
description="Days to look back for trials (global SLS fetch window; auto-expanded to cover any larger league_lookback_days)",
|
|
25
|
+
)
|
|
26
|
+
league_lookback_days: dict[str, int] = Field(
|
|
27
|
+
default_factory=lambda: {"NBA": 90, "NFL": 365},
|
|
28
|
+
description="Per-league lookback (days). Used to filter per-league cached views.",
|
|
24
29
|
)
|
|
25
30
|
trials_limit: int = Field(default=500, description="Max trials to fetch per query")
|
|
26
31
|
|
|
@@ -237,7 +237,11 @@ def register_rest_endpoints(app: FastAPI) -> None:
|
|
|
237
237
|
superbowl_game = next(
|
|
238
238
|
(g for g in all_games if SUPER_BOWL_GAME_ID in g.id), None
|
|
239
239
|
)
|
|
240
|
-
if
|
|
240
|
+
if (
|
|
241
|
+
superbowl_game
|
|
242
|
+
and superbowl_game.status == "live"
|
|
243
|
+
and superbowl_game not in live_games
|
|
244
|
+
):
|
|
241
245
|
live_games = [superbowl_game] + list(live_games)
|
|
242
246
|
|
|
243
247
|
# only for mock test
|
|
@@ -385,9 +389,13 @@ def register_rest_endpoints(app: FastAPI) -> None:
|
|
|
385
389
|
default=None,
|
|
386
390
|
description="Agent type filter: 'built_in' or 'external'.",
|
|
387
391
|
),
|
|
392
|
+
mode: str | None = Query(
|
|
393
|
+
default=None,
|
|
394
|
+
description="Leaderboard mode filter: 'market' or 'prediction'.",
|
|
395
|
+
),
|
|
388
396
|
sort_by: str = Query(
|
|
389
397
|
default="winnings",
|
|
390
|
-
description="Sort field: 'winnings', 'win_rate', 'roi', 'total_bets'.",
|
|
398
|
+
description="Sort field: 'winnings', 'win_rate', 'roi', 'total_bets', 'sharpe', 'prediction_score', 'accuracy', 'total_predictions'.",
|
|
391
399
|
),
|
|
392
400
|
sort_order: str = Query(
|
|
393
401
|
default="desc",
|
|
@@ -413,6 +421,37 @@ def register_rest_endpoints(app: FastAPI) -> None:
|
|
|
413
421
|
"error": f"Invalid period '{period}'. Must be one of: {', '.join(sorted(valid_periods))}"
|
|
414
422
|
},
|
|
415
423
|
)
|
|
424
|
+
valid_modes = {None, "market", "prediction"}
|
|
425
|
+
if mode not in valid_modes:
|
|
426
|
+
return JSONResponse(
|
|
427
|
+
status_code=400,
|
|
428
|
+
content={"error": "Invalid mode. Must be one of: market, prediction."},
|
|
429
|
+
)
|
|
430
|
+
valid_sort_by = {
|
|
431
|
+
"winnings",
|
|
432
|
+
"win_rate",
|
|
433
|
+
"roi",
|
|
434
|
+
"total_bets",
|
|
435
|
+
"sharpe",
|
|
436
|
+
"prediction_score",
|
|
437
|
+
"accuracy",
|
|
438
|
+
"total_predictions",
|
|
439
|
+
}
|
|
440
|
+
if sort_by not in valid_sort_by:
|
|
441
|
+
return JSONResponse(
|
|
442
|
+
status_code=400,
|
|
443
|
+
content={
|
|
444
|
+
"error": f"Invalid sort_by '{sort_by}'. Must be one of: {', '.join(sorted(valid_sort_by))}"
|
|
445
|
+
},
|
|
446
|
+
)
|
|
447
|
+
valid_sort_orders = {"asc", "desc"}
|
|
448
|
+
if sort_order not in valid_sort_orders:
|
|
449
|
+
return JSONResponse(
|
|
450
|
+
status_code=400,
|
|
451
|
+
content={
|
|
452
|
+
"error": f"Invalid sort_order '{sort_order}'. Must be one of: asc, desc"
|
|
453
|
+
},
|
|
454
|
+
)
|
|
416
455
|
|
|
417
456
|
# All paths now read from pre-computed cache
|
|
418
457
|
effective_period = period if period != "all" else None
|
|
@@ -437,16 +476,67 @@ def register_rest_endpoints(app: FastAPI) -> None:
|
|
|
437
476
|
elif agent_type == "built_in":
|
|
438
477
|
leaderboard = [e for e in leaderboard if not e.agent.is_external]
|
|
439
478
|
|
|
440
|
-
#
|
|
441
|
-
|
|
479
|
+
# Mode split: agents are shared across sports, so an agent can have both
|
|
480
|
+
# betting PnL (market) and a prediction score. Filter by *activity* rather
|
|
481
|
+
# than mutual exclusion so a top bettor that also predicted still shows on
|
|
482
|
+
# the market board (with winnings) and on the prediction board (with score).
|
|
483
|
+
if mode == "prediction":
|
|
484
|
+
leaderboard = [e for e in leaderboard if e.prediction_score is not None]
|
|
485
|
+
elif mode == "market":
|
|
486
|
+
leaderboard = [
|
|
487
|
+
e for e in leaderboard if e.total_bets > 0 or e.winnings != 0
|
|
488
|
+
]
|
|
489
|
+
|
|
490
|
+
# 2. Sort (prediction-mode rows use ScoringSys metrics, not betting PnL)
|
|
491
|
+
has_prediction_data = any(e.prediction_score is not None for e in leaderboard)
|
|
492
|
+
is_world_cup_view = league is not None and league.upper() == "WORLD_CUP"
|
|
493
|
+
# mode="market" is an explicit betting view: never remap its sort to
|
|
494
|
+
# prediction_score, even for World Cup. Only an unspecified mode falls
|
|
495
|
+
# back to the league's default (prediction) view.
|
|
496
|
+
is_prediction_view = mode == "prediction" or (
|
|
497
|
+
is_world_cup_view and mode is None
|
|
498
|
+
)
|
|
499
|
+
effective_sort_by = sort_by
|
|
500
|
+
if (
|
|
501
|
+
is_prediction_view
|
|
502
|
+
and has_prediction_data
|
|
503
|
+
and sort_by
|
|
504
|
+
in (
|
|
505
|
+
"winnings",
|
|
506
|
+
"win_rate",
|
|
507
|
+
"roi",
|
|
508
|
+
"total_bets",
|
|
509
|
+
"sharpe",
|
|
510
|
+
)
|
|
511
|
+
):
|
|
512
|
+
effective_sort_by = "prediction_score"
|
|
513
|
+
|
|
514
|
+
if (
|
|
515
|
+
sort_by != "winnings"
|
|
516
|
+
or sort_order != "desc"
|
|
517
|
+
or effective_sort_by != sort_by
|
|
518
|
+
):
|
|
442
519
|
sort_key_map = {
|
|
443
520
|
"winnings": lambda x: x.winnings,
|
|
444
521
|
"win_rate": lambda x: x.win_rate,
|
|
445
522
|
"roi": lambda x: x.roi,
|
|
446
523
|
"sharpe": lambda x: x.sharpe,
|
|
447
524
|
"total_bets": lambda x: x.total_bets,
|
|
525
|
+
"prediction_score": lambda x: (
|
|
526
|
+
x.prediction_score
|
|
527
|
+
if x.prediction_score is not None
|
|
528
|
+
else -float("inf")
|
|
529
|
+
),
|
|
530
|
+
"accuracy": lambda x: (
|
|
531
|
+
x.accuracy if x.accuracy is not None else -float("inf")
|
|
532
|
+
),
|
|
533
|
+
"total_predictions": lambda x: (
|
|
534
|
+
x.total_predictions
|
|
535
|
+
if x.total_predictions is not None
|
|
536
|
+
else -float("inf")
|
|
537
|
+
),
|
|
448
538
|
}
|
|
449
|
-
key_fn = sort_key_map.get(
|
|
539
|
+
key_fn = sort_key_map.get(effective_sort_by, sort_key_map["winnings"])
|
|
450
540
|
leaderboard = sorted(leaderboard, key=key_fn, reverse=(sort_order != "asc"))
|
|
451
541
|
|
|
452
542
|
# 3. Limit
|
|
@@ -42,6 +42,7 @@ class AgentProfileStats(BaseModel):
|
|
|
42
42
|
win_rate: float = Field(default=0.0, serialization_alias="winRate")
|
|
43
43
|
total_bets: int = Field(default=0, serialization_alias="totalBets")
|
|
44
44
|
roi: float = 0.0
|
|
45
|
+
sharpe: float = 0.0
|
|
45
46
|
|
|
46
47
|
|
|
47
48
|
class AgentProfileResponse(BaseModel):
|
|
@@ -75,11 +76,20 @@ class StatsResponse(BaseModel):
|
|
|
75
76
|
|
|
76
77
|
model_config = ConfigDict(frozen=True, populate_by_name=True)
|
|
77
78
|
|
|
79
|
+
# serialization_alias matches the field name; kept for consistency with the
|
|
80
|
+
# rest of the model (every field declares its wire name) and rename-safety.
|
|
81
|
+
mode: Literal["betting", "prediction", "mixed"] = Field(
|
|
82
|
+
default="betting", serialization_alias="mode"
|
|
83
|
+
)
|
|
78
84
|
games_played: int = Field(default=0, serialization_alias="gamesPlayed")
|
|
79
85
|
live_now: int = Field(default=0, serialization_alias="liveNow")
|
|
80
86
|
wagered_today: int = Field(default=0, serialization_alias="wageredToday")
|
|
81
87
|
total_agents: int = Field(default=0, serialization_alias="totalAgents")
|
|
82
88
|
bet_counts: int = Field(default=0, serialization_alias="betCounts")
|
|
89
|
+
prediction_count: int = Field(default=0, serialization_alias="predictionCount")
|
|
90
|
+
prediction_points: float = Field(
|
|
91
|
+
default=0.0, serialization_alias="predictionPoints"
|
|
92
|
+
)
|
|
83
93
|
|
|
84
94
|
|
|
85
95
|
class GameCardData(BaseModel):
|
|
@@ -89,6 +99,11 @@ class GameCardData(BaseModel):
|
|
|
89
99
|
|
|
90
100
|
id: str
|
|
91
101
|
league: str = ""
|
|
102
|
+
# Contest type for sports run as multiple trials per match (e.g. World Cup
|
|
103
|
+
# runs both a window-pool "prediction" trial and a moneyline "betting"
|
|
104
|
+
# trial). Empty when unknown / not applicable. Used by the landing dedup to
|
|
105
|
+
# prefer the prediction trial. See _detect_contest_kind.
|
|
106
|
+
contest_kind: str = Field(default="", serialization_alias="contestKind")
|
|
92
107
|
home_team: TeamIdentity = Field(
|
|
93
108
|
default_factory=TeamIdentity,
|
|
94
109
|
serialization_alias="homeTeam",
|
|
@@ -29,7 +29,7 @@ Filtering:
|
|
|
29
29
|
|
|
30
30
|
Supported endpoints: /api/landing, /api/stats, /api/games, /api/leaderboard, /api/agent-actions
|
|
31
31
|
|
|
32
|
-
Per-league results are cached separately for leagues in CACHEABLE_LEAGUES
|
|
32
|
+
Per-league results are cached separately for leagues in CACHEABLE_LEAGUES.
|
|
33
33
|
To add a new league, update CACHEABLE_LEAGUES in the code.
|
|
34
34
|
|
|
35
35
|
Configuration:
|
|
@@ -90,6 +90,7 @@ from dojozero.arena_server._utils import (
|
|
|
90
90
|
_compute_leaderboard,
|
|
91
91
|
_compute_leaderboard_from_spans,
|
|
92
92
|
_load_replay_data,
|
|
93
|
+
ARENA_RENDERED_OPERATIONS,
|
|
93
94
|
TRIAL_INFO_OPERATION_NAMES,
|
|
94
95
|
trial_id_for_span_grouping,
|
|
95
96
|
)
|
|
@@ -789,7 +790,11 @@ class BackgroundRefresher:
|
|
|
789
790
|
tid: str, span_start: datetime | None
|
|
790
791
|
) -> tuple[str, list[SpanData]]:
|
|
791
792
|
async with sem:
|
|
792
|
-
spans = await self.trace_reader.get_spans(
|
|
793
|
+
spans = await self.trace_reader.get_spans(
|
|
794
|
+
tid,
|
|
795
|
+
start_time=span_start,
|
|
796
|
+
operation_names=ARENA_RENDERED_OPERATIONS,
|
|
797
|
+
)
|
|
793
798
|
return tid, spans
|
|
794
799
|
|
|
795
800
|
if is_initial or self._last_span_fetch_time is None:
|
|
@@ -1417,7 +1422,9 @@ class BackgroundRefresher:
|
|
|
1417
1422
|
|
|
1418
1423
|
# Fallback to SLS (slow path)
|
|
1419
1424
|
if not spans:
|
|
1420
|
-
spans = await self.trace_reader.get_spans(
|
|
1425
|
+
spans = await self.trace_reader.get_spans(
|
|
1426
|
+
trial_id, operation_names=ARENA_RENDERED_OPERATIONS
|
|
1427
|
+
)
|
|
1421
1428
|
|
|
1422
1429
|
existing = self.cache.get_trial_details(trial_id)
|
|
1423
1430
|
|