eggpool 0.3.3__tar.gz → 0.3.4__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 (237) hide show
  1. {eggpool-0.3.3 → eggpool-0.3.4}/AGENTS.md +1 -0
  2. {eggpool-0.3.3 → eggpool-0.3.4}/CHANGELOG.md +7 -0
  3. {eggpool-0.3.3 → eggpool-0.3.4}/PKG-INFO +1 -1
  4. {eggpool-0.3.3 → eggpool-0.3.4}/docs/providers.md +19 -2
  5. {eggpool-0.3.3 → eggpool-0.3.4}/pyproject.toml +1 -1
  6. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/dashboard/render.py +21 -4
  7. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/providers/_templates.toml +28 -0
  8. {eggpool-0.3.3 → eggpool-0.3.4}/uv.lock +1 -1
  9. {eggpool-0.3.3 → eggpool-0.3.4}/.env.example +0 -0
  10. {eggpool-0.3.3 → eggpool-0.3.4}/.github/workflows/ci.yml +0 -0
  11. {eggpool-0.3.3 → eggpool-0.3.4}/.github/workflows/release.yml +0 -0
  12. {eggpool-0.3.3 → eggpool-0.3.4}/.gitignore +0 -0
  13. {eggpool-0.3.3 → eggpool-0.3.4}/LICENSE +0 -0
  14. {eggpool-0.3.3 → eggpool-0.3.4}/README.md +0 -0
  15. {eggpool-0.3.3 → eggpool-0.3.4}/architecture/README.md +0 -0
  16. {eggpool-0.3.3 → eggpool-0.3.4}/config-examples/claude-code.env +0 -0
  17. {eggpool-0.3.3 → eggpool-0.3.4}/config-examples/opencode.jsonc +0 -0
  18. {eggpool-0.3.3 → eggpool-0.3.4}/config.example.toml +0 -0
  19. {eggpool-0.3.3 → eggpool-0.3.4}/deploy/eggpool-logrotate.conf +0 -0
  20. {eggpool-0.3.3 → eggpool-0.3.4}/deploy/eggpool.service +0 -0
  21. {eggpool-0.3.3 → eggpool-0.3.4}/deploy/env.example +0 -0
  22. {eggpool-0.3.3 → eggpool-0.3.4}/docs/backup-restore.md +0 -0
  23. {eggpool-0.3.3 → eggpool-0.3.4}/docs/deployment.md +0 -0
  24. {eggpool-0.3.3 → eggpool-0.3.4}/docs/filesystem-layout.md +0 -0
  25. {eggpool-0.3.3 → eggpool-0.3.4}/docs/firewall.md +0 -0
  26. {eggpool-0.3.3 → eggpool-0.3.4}/docs/model-limits.md +0 -0
  27. {eggpool-0.3.3 → eggpool-0.3.4}/docs/network-diagnostics.md +0 -0
  28. {eggpool-0.3.3 → eggpool-0.3.4}/docs/proxy.md +0 -0
  29. {eggpool-0.3.3 → eggpool-0.3.4}/docs/raspberry-pi.md +0 -0
  30. {eggpool-0.3.3 → eggpool-0.3.4}/scripts/__init__.py +0 -0
  31. {eggpool-0.3.3 → eggpool-0.3.4}/scripts/check_database.py +0 -0
  32. {eggpool-0.3.3 → eggpool-0.3.4}/scripts/install.sh +0 -0
  33. {eggpool-0.3.3 → eggpool-0.3.4}/scripts/install_prompt.py +0 -0
  34. {eggpool-0.3.3 → eggpool-0.3.4}/scripts/smoke_test.py +0 -0
  35. {eggpool-0.3.3 → eggpool-0.3.4}/scripts/verify_upstream_auth.py +0 -0
  36. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/__init__.py +0 -0
  37. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/__main__.py +0 -0
  38. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/_share/.env.example +0 -0
  39. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/_share/config.example.toml +0 -0
  40. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/accounts/__init__.py +0 -0
  41. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/accounts/registry.py +0 -0
  42. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/accounts/state.py +0 -0
  43. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/api/__init__.py +0 -0
  44. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/api/backoff.py +0 -0
  45. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/api/chat_completions.py +0 -0
  46. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/api/errors.py +0 -0
  47. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/api/messages.py +0 -0
  48. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/api/models.py +0 -0
  49. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/api/network.py +0 -0
  50. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/api/proxy_request.py +0 -0
  51. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/api/runtime.py +0 -0
  52. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/api/stats.py +0 -0
  53. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/api/update.py +0 -0
  54. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/app.py +0 -0
  55. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/auth.py +0 -0
  56. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/background/__init__.py +0 -0
  57. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/background/backup.py +0 -0
  58. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/background/cleanup.py +0 -0
  59. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/catalog/__init__.py +0 -0
  60. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/catalog/cache.py +0 -0
  61. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/catalog/catalog_resolvers.py +0 -0
  62. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/catalog/fetcher.py +0 -0
  63. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/catalog/limits.py +0 -0
  64. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/catalog/normalizer.py +0 -0
  65. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/catalog/pricing.py +0 -0
  66. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/catalog/pricing_aliases.py +0 -0
  67. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/catalog/pricing_resolver.py +0 -0
  68. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/catalog/protocols.py +0 -0
  69. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/catalog/service.py +0 -0
  70. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/cli.py +0 -0
  71. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/cli_full.py +0 -0
  72. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/config.py +0 -0
  73. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/constants.py +0 -0
  74. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/cost_recompute.py +0 -0
  75. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/dashboard/__init__.py +0 -0
  76. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/dashboard/_resources.py +0 -0
  77. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/dashboard/escape.py +0 -0
  78. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/dashboard/routes.py +0 -0
  79. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/dashboard/static/chart.umd.min.js +0 -0
  80. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/dashboard/static/dashboard.css +0 -0
  81. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/dashboard/static/dashboard.js +0 -0
  82. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/dashboard/static/favicon.svg +0 -0
  83. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/dashboard/theme.py +0 -0
  84. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/dashboard/themes/Booberry.toml +0 -0
  85. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/dashboard/themes/Catppuccin Latte.toml +0 -0
  86. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/dashboard/themes/Catppuccin Macchiato.toml +0 -0
  87. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/dashboard/themes/Catppuccin Mocha.toml +0 -0
  88. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/dashboard/themes/Cyber Red.toml +0 -0
  89. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/dashboard/themes/Cyberpunk.toml +0 -0
  90. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/dashboard/themes/Dark Green.toml +0 -0
  91. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/dashboard/themes/Discord (80_ Saturation).toml +0 -0
  92. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/dashboard/themes/Discord.toml +0 -0
  93. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/dashboard/themes/Dracula.toml +0 -0
  94. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/dashboard/themes/Ferra Light.toml +0 -0
  95. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/dashboard/themes/Flexor Dark.toml +0 -0
  96. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/dashboard/themes/Gruvbox.toml +0 -0
  97. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/dashboard/themes/Halcyon Dark.toml +0 -0
  98. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/dashboard/themes/IntelliJ Light.toml +0 -0
  99. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/dashboard/themes/Kanagawa.toml +0 -0
  100. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/dashboard/themes/Macaw Dark.toml +0 -0
  101. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/dashboard/themes/Macaw Light.toml +0 -0
  102. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/dashboard/themes/Matrix.toml +0 -0
  103. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/dashboard/themes/Noctis Lilac.toml +0 -0
  104. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/dashboard/themes/Nord.toml +0 -0
  105. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/dashboard/themes/Nostromo Terminal.toml +0 -0
  106. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/dashboard/themes/One Dark.toml +0 -0
  107. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/dashboard/themes/Oxocarbon.toml +0 -0
  108. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/dashboard/themes/Rose Pine Dawn.toml +0 -0
  109. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/dashboard/themes/Rose Pine Moon.toml +0 -0
  110. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/dashboard/themes/Rose Pine.toml +0 -0
  111. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/dashboard/themes/Solarized Dark.toml +0 -0
  112. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/dashboard/themes/Sonokai.toml +0 -0
  113. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/dashboard/themes/Tokyo Night Storm.toml +0 -0
  114. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/dashboard/themes/VESPER.toml +0 -0
  115. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/dashboard/themes/Zenburn.toml +0 -0
  116. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/dashboard/themes/acton.toml +0 -0
  117. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/dashboard/themes/bam.toml +0 -0
  118. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/dashboard/themes/base16-atelier-forest-light.toml +0 -0
  119. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/dashboard/themes/berlin.toml +0 -0
  120. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/dashboard/themes/black but with important highlights.toml +0 -0
  121. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/dashboard/themes/broc.toml +0 -0
  122. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/dashboard/themes/cork.toml +0 -0
  123. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/dashboard/themes/ferra.toml +0 -0
  124. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/dashboard/themes/forest.toml +0 -0
  125. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/dashboard/themes/lisbon.toml +0 -0
  126. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/dashboard/themes/midnight.toml +0 -0
  127. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/dashboard/themes/oslo.toml +0 -0
  128. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/dashboard/themes/plum.toml +0 -0
  129. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/dashboard/themes/portland.toml +0 -0
  130. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/dashboard/themes/sunset.toml +0 -0
  131. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/dashboard/themes/tofino.toml +0 -0
  132. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/dashboard/themes/vanimo.toml +0 -0
  133. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/dashboard/themes/vik.toml +0 -0
  134. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/db/__init__.py +0 -0
  135. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/db/connection.py +0 -0
  136. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/db/migrations.py +0 -0
  137. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/db/repositories.py +0 -0
  138. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/db/rollup_repository.py +0 -0
  139. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/db/schema/0001_initial.sql +0 -0
  140. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/db/schema/0002_indexes.sql +0 -0
  141. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/db/schema/0003_request_attempts.sql +0 -0
  142. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/db/schema/0004_integration_hardening.sql +0 -0
  143. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/db/schema/0005_price_microdollars.sql +0 -0
  144. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/db/schema/0006_correct_price_microdollars.sql +0 -0
  145. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/db/schema/0007_price_cache_rates.sql +0 -0
  146. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/db/schema/0008_proxy_request_identity.sql +0 -0
  147. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/db/schema/0009_model_protocol_source.sql +0 -0
  148. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/db/schema/0010_health_probe.sql +0 -0
  149. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/db/schema/0011_model_resolution_status.sql +0 -0
  150. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/db/schema/0012_drop_reservations_estimated_microdollars.sql +0 -0
  151. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/db/schema/0013_request_attempts_account_id_index.sql +0 -0
  152. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/db/schema/0014_bandwidth_tracking.sql +0 -0
  153. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/db/schema/0015_multi_provider.sql +0 -0
  154. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/db/schema/0016_requests_provider_id.sql +0 -0
  155. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/db/schema/0017_price_snapshots_provider_id.sql +0 -0
  156. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/db/schema/0018_provider_pings.sql +0 -0
  157. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/db/schema/0019_client_ip.sql +0 -0
  158. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/db/schema/0020_performance_indexes.sql +0 -0
  159. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/db/schema/0021_provider_model_metadata.sql +0 -0
  160. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/db/schema/0022_dashboard_indexes.sql +0 -0
  161. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/db/schema/0023_deprecated_model_placeholder.sql +0 -0
  162. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/db/schema/0024_account_backoffs.sql +0 -0
  163. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/db/schema/0025_stale_request_index.sql +0 -0
  164. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/db/schema/0026_attempt_observability.sql +0 -0
  165. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/db/schema/0027_routing_decisions.sql +0 -0
  166. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/db/schema/0028_operational_events.sql +0 -0
  167. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/db/schema/0029_latency_phases.sql +0 -0
  168. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/db/schema/0030_model_pricing_aliases.sql +0 -0
  169. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/db/schema/0031_price_snapshot_provenance.sql +0 -0
  170. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/db/schema/0032_usage_rollups.sql +0 -0
  171. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/db/schema/0033_request_provider_local_cost.sql +0 -0
  172. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/db/schema/checksums.json +0 -0
  173. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/deploy/__init__.py +0 -0
  174. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/deploy_user.py +0 -0
  175. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/errors.py +0 -0
  176. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/fastcli.py +0 -0
  177. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/health/__init__.py +0 -0
  178. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/health/backoff.py +0 -0
  179. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/health/circuit_breaker.py +0 -0
  180. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/health/health_manager.py +0 -0
  181. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/integrations/__init__.py +0 -0
  182. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/integrations/opencode.py +0 -0
  183. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/lifecycle/__init__.py +0 -0
  184. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/lifecycle/backup.py +0 -0
  185. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/lifecycle/uninstall.py +0 -0
  186. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/logging.py +0 -0
  187. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/metrics/__init__.py +0 -0
  188. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/metrics/buffer.py +0 -0
  189. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/models/__init__.py +0 -0
  190. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/models/api.py +0 -0
  191. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/models/config.py +0 -0
  192. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/models/database.py +0 -0
  193. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/models/domain.py +0 -0
  194. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/onboard.py +0 -0
  195. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/providers/__init__.py +0 -0
  196. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/providers/auth.py +0 -0
  197. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/providers/client_pool.py +0 -0
  198. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/providers/connect.py +0 -0
  199. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/providers/contract.py +0 -0
  200. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/providers/dns_cache.py +0 -0
  201. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/providers/outbound.py +0 -0
  202. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/providers/pproxy_transport.py +0 -0
  203. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/proxy/__init__.py +0 -0
  204. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/proxy/client.py +0 -0
  205. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/proxy/cost_reporting.py +0 -0
  206. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/proxy/sse_observer.py +0 -0
  207. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/proxy/usage.py +0 -0
  208. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/py.typed +0 -0
  209. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/quota/__init__.py +0 -0
  210. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/quota/audit.py +0 -0
  211. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/quota/estimation.py +0 -0
  212. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/quota/reservation.py +0 -0
  213. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/quota/scorer.py +0 -0
  214. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/request/__init__.py +0 -0
  215. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/request/attempt_finalizer.py +0 -0
  216. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/request/body.py +0 -0
  217. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/request/coordinator.py +0 -0
  218. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/request/finalizer.py +0 -0
  219. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/request/limits.py +0 -0
  220. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/retry/__init__.py +0 -0
  221. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/retry/classification.py +0 -0
  222. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/routing/__init__.py +0 -0
  223. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/routing/eligibility.py +0 -0
  224. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/routing/provider.py +0 -0
  225. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/routing/router.py +0 -0
  226. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/runtime.py +0 -0
  227. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/runtime_dispatch.py +0 -0
  228. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/runtime_metrics.py +0 -0
  229. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/runtime_paths.py +0 -0
  230. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/security/__init__.py +0 -0
  231. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/security/redaction.py +0 -0
  232. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/stats/__init__.py +0 -0
  233. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/stats/grouped_timeseries.py +0 -0
  234. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/stats/queries.py +0 -0
  235. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/stats/service.py +0 -0
  236. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/toml_edit.py +0 -0
  237. {eggpool-0.3.3 → eggpool-0.3.4}/src/eggpool/update_checker.py +0 -0
@@ -90,6 +90,7 @@ Use the hierarchy in `errors.py`. Chain exceptions with `raise ... from err` or
90
90
 
91
91
  - Configuration changes require a service restart; live reload is intentionally not supported
92
92
  - No pre-commit hooks are configured in this repo; CI runs ruff, pyright, and pytest via GitHub Actions
93
+ - **`static_models` is the source of truth for provider-specific protocol** — `FAMILY_PROTOCOLS` (`src/eggpool/catalog/protocols.py`) is a global fallback that applies when no explicit override exists. Providers like `minimax-cn` that serve MiniMax models on the OpenAI-compatible surface **must** ship `[[providers.<id>.static_models]]` rows with `protocol = "openai"`, otherwise the live `/v1/models` fetch resolves `MiniMax-M*` via the `minimax-` family prefix to `anthropic` and the provider protocol constraint check (`src/eggpool/catalog/service.py:533-545`) clears the protocol to `None`, producing `ModelUnavailableError("Model 'MiniMax-M3' has unresolved protocol")` instead of the more obvious 400 `ProtocolMismatchError`. Static seeds with `protocol_source = "static_config"` survive the live merge via `ModelCatalogCache._preserve_static_fields` (`src/eggpool/catalog/cache.py:146-187`). The same model ID may also be flipped on a per-provider basis via `[providers.<id>.model_overrides."<model-id>"].protocol = "openai"` for operator overrides that go beyond the bundled template.
93
94
  - `Database.vacuum()` is the only sanctioned path for `VACUUM` in production code
94
95
  - Every DML write must run inside `async with db.transaction():`
95
96
  - SQLite transactions are serialized across concurrent tasks via a single connection lock + ContextVar
@@ -7,6 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.3.4] - 2026-06-27
11
+
12
+ ### Fixed
13
+
14
+ - **Exclusion taxonomy empty-state**: the Routing page's doughnut chart now shows `<p class="empty">No exclusion data in this period.</p>` instead of an invisible Chart.js ring when no exclusions have been recorded in the selected period. The previous behaviour rendered a zero-data doughnut whose legend was visible but the chart itself was not, producing a "key but no graph" artefact.
15
+ - **`circuit_breaker` classification**: `SUPPRESSIVE_EXCLUSION_REASONS` now includes `circuit_breaker`, the only exclusion reason the coordinator actually writes to `exclude_reasons_json`. Previously every real-world exclusion landed in the `unknown` bucket because the frozenset only contained the legacy `circuit_open` name.
16
+
10
17
  ### Added
11
18
 
12
19
  - **Sticky dashboard topbar**: `header.topbar` is `position: sticky; top: 0; z-index: 5` with a subtle backdrop blur, so the page navigation stays visible while scrolling on desktop. Mobile layout is unchanged (the topnav disclosure still wraps cleanly under 480px).
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: eggpool
3
- Version: 0.3.3
3
+ Version: 0.3.4
4
4
  Summary: A lightweight proxy that aggregates multiple LLM provider accounts behind one OpenAI-compatible endpoint
5
5
  Project-URL: Homepage, https://github.com/eggstack/eggpool
6
6
  Project-URL: Repository, https://github.com/eggstack/eggpool
@@ -170,11 +170,28 @@ Live model discovery fetches the catalog from the MiniMax `/v1/models`
170
170
  endpoint using the documented Anthropic-compatible listing. The static
171
171
  seeds serve only as a fallback when live discovery is unavailable.
172
172
 
173
- `minimax-cn` (China console) is intentionally still configured as plain
173
+ `minimax-cn` (China console) is intentionally configured as plain
174
174
  OpenAI-compatible in the bundled template because the China endpoint
175
175
  family and auth shape have not been confirmed against `api.minimaxi.com`.
176
176
  Do not assume parity with the international Anthropic-compatible
177
- template without live testing.
177
+ template without live testing. `minimax-cn` ships with
178
+ `[[providers.minimax-cn.static_models]]` rows pinning `MiniMax-M3`,
179
+ `MiniMax-M2.7`, and `MiniMax-M2.5` to `protocol = "openai"` so the
180
+ global `FAMILY_PROTOCOLS["minimax-"] = "anthropic"` mapping does not
181
+ clear the protocol at the provider constraint check. Route MiniMax
182
+ through `minimax-cn` on `/v1/chat/completions` (OpenAI), not
183
+ `/v1/messages`.
184
+
185
+ ### Endpoint routing by MiniMax provider
186
+
187
+ | Provider | Base URL | Endpoint | Auth style |
188
+ | ------------------- | --------------------------------------- | ----------------------- | ------------ |
189
+ | `minimax` | `https://api.minimax.io/anthropic` | `POST /v1/messages` | `x-api-key` |
190
+ | `minimax-cn` | `https://api.minimaxi.com/v1` | `POST /chat/completions`| `Bearer` |
191
+
192
+ Requests that hit the wrong endpoint receive a `400 ProtocolMismatchError`
193
+ ("Model 'MiniMax-M3' uses the X protocol. Use /v1/..."). Hit the row
194
+ that matches the provider you configured.
178
195
 
179
196
  ### GeneralCompute PAYG (Plain OpenAI-Compatible)
180
197
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "eggpool"
3
- version = "0.3.3"
3
+ version = "0.3.4"
4
4
  description = "A lightweight proxy that aggregates multiple LLM provider accounts behind one OpenAI-compatible endpoint"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.11"
@@ -94,6 +94,13 @@ _STATUS_BADGE_TOOLTIPS: dict[str, str] = {
94
94
  # signals). This split lets the dashboard verify the design rule that
95
95
  # upstream-observed failures control exclusion while local accounting
96
96
  # only influences priority.
97
+ #
98
+ # ``circuit_breaker`` is the only reason the coordinator actually writes
99
+ # to ``exclude_reasons_json`` (see
100
+ # ``eggpool.request.coordinator._score_and_select``). ``circuit_open``
101
+ # is kept for backwards compatibility with rows written before the
102
+ # coordinator rename and to align semantically with the
103
+ # ``_STATUS_BADGE_TOOLTIPS`` mapping above.
97
104
  SUPPRESSIVE_EXCLUSION_REASONS: frozenset[str] = frozenset(
98
105
  {
99
106
  "authentication_failed",
@@ -107,6 +114,7 @@ SUPPRESSIVE_EXCLUSION_REASONS: frozenset[str] = frozenset(
107
114
  "account_disabled",
108
115
  "protocol_mismatch",
109
116
  "circuit_open",
117
+ "circuit_breaker",
110
118
  }
111
119
  )
112
120
 
@@ -459,12 +467,17 @@ def _render_layout(
459
467
  script_block = (
460
468
  _render_auto_refresh_script(refresh_interval_s) if auto_refresh else ""
461
469
  )
470
+ # `dashboard.js` is intentionally always-on: it wires the mobile
471
+ # burger menu, the update-command copy affordance, and the
472
+ # timeseries controls. Its init functions guard themselves with
473
+ # empty-result DOM queries so they are no-ops on pages that do not
474
+ # use charts or timeseries. Only `chart.js` is gated behind
475
+ # `include_chart_js` because it is ~200 KB and we want to keep it
476
+ # off the critical path for non-chart pages.
462
477
  chart_script = (
463
- '<script defer src="/static/chart.js"></script>'
464
- '<script defer src="/static/dashboard.js"></script>'
465
- if include_chart_js
466
- else ""
478
+ '<script defer src="/static/chart.js"></script>' if include_chart_js else ""
467
479
  )
480
+ dashboard_script = '<script defer src="/static/dashboard.js"></script>'
468
481
  update_indicator = _render_update_indicator(update_info)
469
482
  return f"""<!DOCTYPE html>
470
483
  <html lang="en">
@@ -508,6 +521,7 @@ def _render_layout(
508
521
  </footer>
509
522
  {script_block}
510
523
  {chart_script}
524
+ {dashboard_script}
511
525
  </body>
512
526
  </html>"""
513
527
 
@@ -3630,6 +3644,9 @@ def _render_exclusion_taxonomy_chart(
3630
3644
  category = _classify_exclusion(reason)
3631
3645
  category_totals[category] = category_totals.get(category, 0) + count
3632
3646
 
3647
+ if sum(category_totals.values()) == 0:
3648
+ return '<p class="empty">No exclusion data in this period.</p>'
3649
+
3633
3650
  labels = json.dumps(["Suppressive", "Advisory", "Unknown"])
3634
3651
  datasets = json.dumps(
3635
3652
  [
@@ -113,6 +113,34 @@ probe_model = "MiniMax-M2.5"
113
113
  probe_protocol = "openai"
114
114
  require_models = false
115
115
 
116
+ # MiniMax China serves the same model IDs as MiniMax International but
117
+ # via an OpenAI-compatible surface. Pin the protocol here so the global
118
+ # FAMILY_PROTOCOLS["minimax-"] = "anthropic" mapping does not clear the
119
+ # protocol during the provider protocol constraint check (see
120
+ # CatalogService._fetch_and_process_account). Without these seeds
121
+ # MiniMax-M* would be served with protocol = None and rejected at
122
+ # RequestCoordinator._validate_endpoint.
123
+ [[providers.minimax-cn.static_models]]
124
+ id = "MiniMax-M3"
125
+ display_name = "MiniMax-M3"
126
+ protocol = "openai"
127
+ supports_tools = true
128
+ supports_vision = false
129
+
130
+ [[providers.minimax-cn.static_models]]
131
+ id = "MiniMax-M2.7"
132
+ display_name = "MiniMax-M2.7"
133
+ protocol = "openai"
134
+ supports_tools = true
135
+ supports_vision = false
136
+
137
+ [[providers.minimax-cn.static_models]]
138
+ id = "MiniMax-M2.5"
139
+ display_name = "MiniMax-M2.5"
140
+ protocol = "openai"
141
+ supports_tools = true
142
+ supports_vision = false
143
+
116
144
  [providers.generalcompute]
117
145
  # GeneralCompute — plain OpenAI-compatible PAYG.
118
146
  # Treat as standard OpenAI surface (GET /models, POST /chat/completions,
@@ -196,7 +196,7 @@ wheels = [
196
196
 
197
197
  [[package]]
198
198
  name = "eggpool"
199
- version = "0.3.2"
199
+ version = "0.3.4"
200
200
  source = { editable = "." }
201
201
  dependencies = [
202
202
  { name = "aiosqlite" },
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes