eggpool 0.3.7__tar.gz → 0.3.8__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 (252) hide show
  1. {eggpool-0.3.7 → eggpool-0.3.8}/PKG-INFO +1 -1
  2. {eggpool-0.3.7 → eggpool-0.3.8}/pyproject.toml +1 -1
  3. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/catalog/catalog_resolvers.py +119 -24
  4. {eggpool-0.3.7 → eggpool-0.3.8}/.env.example +0 -0
  5. {eggpool-0.3.7 → eggpool-0.3.8}/.github/workflows/ci.yml +0 -0
  6. {eggpool-0.3.7 → eggpool-0.3.8}/.github/workflows/release.yml +0 -0
  7. {eggpool-0.3.7 → eggpool-0.3.8}/.gitignore +0 -0
  8. {eggpool-0.3.7 → eggpool-0.3.8}/AGENTS.md +0 -0
  9. {eggpool-0.3.7 → eggpool-0.3.8}/CHANGELOG.md +0 -0
  10. {eggpool-0.3.7 → eggpool-0.3.8}/LICENSE +0 -0
  11. {eggpool-0.3.7 → eggpool-0.3.8}/README.md +0 -0
  12. {eggpool-0.3.7 → eggpool-0.3.8}/architecture/README.md +0 -0
  13. {eggpool-0.3.7 → eggpool-0.3.8}/config-examples/claude-code.env +0 -0
  14. {eggpool-0.3.7 → eggpool-0.3.8}/config-examples/opencode.jsonc +0 -0
  15. {eggpool-0.3.7 → eggpool-0.3.8}/config.example.toml +0 -0
  16. {eggpool-0.3.7 → eggpool-0.3.8}/deploy/eggpool-logrotate.conf +0 -0
  17. {eggpool-0.3.7 → eggpool-0.3.8}/deploy/eggpool.service +0 -0
  18. {eggpool-0.3.7 → eggpool-0.3.8}/deploy/env.example +0 -0
  19. {eggpool-0.3.7 → eggpool-0.3.8}/docs/backup-restore.md +0 -0
  20. {eggpool-0.3.7 → eggpool-0.3.8}/docs/deployment.md +0 -0
  21. {eggpool-0.3.7 → eggpool-0.3.8}/docs/filesystem-layout.md +0 -0
  22. {eggpool-0.3.7 → eggpool-0.3.8}/docs/firewall.md +0 -0
  23. {eggpool-0.3.7 → eggpool-0.3.8}/docs/model-limits.md +0 -0
  24. {eggpool-0.3.7 → eggpool-0.3.8}/docs/network-diagnostics.md +0 -0
  25. {eggpool-0.3.7 → eggpool-0.3.8}/docs/providers.md +0 -0
  26. {eggpool-0.3.7 → eggpool-0.3.8}/docs/proxy.md +0 -0
  27. {eggpool-0.3.7 → eggpool-0.3.8}/docs/raspberry-pi.md +0 -0
  28. {eggpool-0.3.7 → eggpool-0.3.8}/docs/transcoding.md +0 -0
  29. {eggpool-0.3.7 → eggpool-0.3.8}/scripts/__init__.py +0 -0
  30. {eggpool-0.3.7 → eggpool-0.3.8}/scripts/check_database.py +0 -0
  31. {eggpool-0.3.7 → eggpool-0.3.8}/scripts/install.sh +0 -0
  32. {eggpool-0.3.7 → eggpool-0.3.8}/scripts/install_prompt.py +0 -0
  33. {eggpool-0.3.7 → eggpool-0.3.8}/scripts/smoke_test.py +0 -0
  34. {eggpool-0.3.7 → eggpool-0.3.8}/scripts/validate_routing.py +0 -0
  35. {eggpool-0.3.7 → eggpool-0.3.8}/scripts/verify_upstream_auth.py +0 -0
  36. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/__init__.py +0 -0
  37. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/__main__.py +0 -0
  38. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/_share/.env.example +0 -0
  39. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/_share/config.example.toml +0 -0
  40. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/accounts/__init__.py +0 -0
  41. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/accounts/registry.py +0 -0
  42. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/accounts/state.py +0 -0
  43. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/api/__init__.py +0 -0
  44. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/api/backoff.py +0 -0
  45. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/api/chat_completions.py +0 -0
  46. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/api/errors.py +0 -0
  47. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/api/messages.py +0 -0
  48. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/api/models.py +0 -0
  49. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/api/network.py +0 -0
  50. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/api/proxy_request.py +0 -0
  51. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/api/runtime.py +0 -0
  52. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/api/stats.py +0 -0
  53. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/api/update.py +0 -0
  54. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/app.py +0 -0
  55. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/auth.py +0 -0
  56. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/background/__init__.py +0 -0
  57. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/background/backup.py +0 -0
  58. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/background/cleanup.py +0 -0
  59. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/catalog/__init__.py +0 -0
  60. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/catalog/cache.py +0 -0
  61. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/catalog/fetcher.py +0 -0
  62. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/catalog/limits.py +0 -0
  63. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/catalog/normalizer.py +0 -0
  64. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/catalog/pricing.py +0 -0
  65. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/catalog/pricing_aliases.py +0 -0
  66. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/catalog/pricing_resolver.py +0 -0
  67. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/catalog/protocols.py +0 -0
  68. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/catalog/service.py +0 -0
  69. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/cli.py +0 -0
  70. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/cli_full.py +0 -0
  71. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/config.py +0 -0
  72. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/constants.py +0 -0
  73. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/cost_recompute.py +0 -0
  74. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/dashboard/__init__.py +0 -0
  75. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/dashboard/_resources.py +0 -0
  76. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/dashboard/escape.py +0 -0
  77. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/dashboard/render.py +0 -0
  78. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/dashboard/routes.py +0 -0
  79. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/dashboard/static/chart.umd.min.js +0 -0
  80. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/dashboard/static/dashboard.css +0 -0
  81. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/dashboard/static/dashboard.js +0 -0
  82. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/dashboard/static/favicon.svg +0 -0
  83. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/dashboard/theme.py +0 -0
  84. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/dashboard/themes/Booberry.toml +0 -0
  85. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/dashboard/themes/Catppuccin Latte.toml +0 -0
  86. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/dashboard/themes/Catppuccin Macchiato.toml +0 -0
  87. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/dashboard/themes/Catppuccin Mocha.toml +0 -0
  88. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/dashboard/themes/Cyber Red.toml +0 -0
  89. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/dashboard/themes/Cyberpunk.toml +0 -0
  90. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/dashboard/themes/Dark Green.toml +0 -0
  91. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/dashboard/themes/Discord (80_ Saturation).toml +0 -0
  92. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/dashboard/themes/Discord.toml +0 -0
  93. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/dashboard/themes/Dracula.toml +0 -0
  94. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/dashboard/themes/Ferra Light.toml +0 -0
  95. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/dashboard/themes/Flexor Dark.toml +0 -0
  96. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/dashboard/themes/Gruvbox.toml +0 -0
  97. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/dashboard/themes/Halcyon Dark.toml +0 -0
  98. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/dashboard/themes/IntelliJ Light.toml +0 -0
  99. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/dashboard/themes/Kanagawa.toml +0 -0
  100. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/dashboard/themes/Macaw Dark.toml +0 -0
  101. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/dashboard/themes/Macaw Light.toml +0 -0
  102. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/dashboard/themes/Matrix.toml +0 -0
  103. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/dashboard/themes/Noctis Lilac.toml +0 -0
  104. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/dashboard/themes/Nord.toml +0 -0
  105. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/dashboard/themes/Nostromo Terminal.toml +0 -0
  106. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/dashboard/themes/One Dark.toml +0 -0
  107. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/dashboard/themes/Oxocarbon.toml +0 -0
  108. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/dashboard/themes/Rose Pine Dawn.toml +0 -0
  109. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/dashboard/themes/Rose Pine Moon.toml +0 -0
  110. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/dashboard/themes/Rose Pine.toml +0 -0
  111. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/dashboard/themes/Solarized Dark.toml +0 -0
  112. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/dashboard/themes/Sonokai.toml +0 -0
  113. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/dashboard/themes/Tokyo Night Storm.toml +0 -0
  114. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/dashboard/themes/VESPER.toml +0 -0
  115. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/dashboard/themes/Zenburn.toml +0 -0
  116. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/dashboard/themes/acton.toml +0 -0
  117. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/dashboard/themes/bam.toml +0 -0
  118. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/dashboard/themes/base16-atelier-forest-light.toml +0 -0
  119. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/dashboard/themes/berlin.toml +0 -0
  120. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/dashboard/themes/black but with important highlights.toml +0 -0
  121. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/dashboard/themes/broc.toml +0 -0
  122. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/dashboard/themes/cork.toml +0 -0
  123. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/dashboard/themes/ferra.toml +0 -0
  124. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/dashboard/themes/forest.toml +0 -0
  125. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/dashboard/themes/lisbon.toml +0 -0
  126. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/dashboard/themes/midnight.toml +0 -0
  127. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/dashboard/themes/oslo.toml +0 -0
  128. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/dashboard/themes/plum.toml +0 -0
  129. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/dashboard/themes/portland.toml +0 -0
  130. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/dashboard/themes/sunset.toml +0 -0
  131. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/dashboard/themes/tofino.toml +0 -0
  132. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/dashboard/themes/vanimo.toml +0 -0
  133. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/dashboard/themes/vik.toml +0 -0
  134. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/db/__init__.py +0 -0
  135. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/db/connection.py +0 -0
  136. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/db/migrations.py +0 -0
  137. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/db/repositories.py +0 -0
  138. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/db/rollup_repository.py +0 -0
  139. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/db/schema/0001_initial.sql +0 -0
  140. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/db/schema/0002_indexes.sql +0 -0
  141. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/db/schema/0003_request_attempts.sql +0 -0
  142. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/db/schema/0004_integration_hardening.sql +0 -0
  143. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/db/schema/0005_price_microdollars.sql +0 -0
  144. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/db/schema/0006_correct_price_microdollars.sql +0 -0
  145. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/db/schema/0007_price_cache_rates.sql +0 -0
  146. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/db/schema/0008_proxy_request_identity.sql +0 -0
  147. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/db/schema/0009_model_protocol_source.sql +0 -0
  148. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/db/schema/0010_health_probe.sql +0 -0
  149. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/db/schema/0011_model_resolution_status.sql +0 -0
  150. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/db/schema/0012_drop_reservations_estimated_microdollars.sql +0 -0
  151. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/db/schema/0013_request_attempts_account_id_index.sql +0 -0
  152. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/db/schema/0014_bandwidth_tracking.sql +0 -0
  153. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/db/schema/0015_multi_provider.sql +0 -0
  154. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/db/schema/0016_requests_provider_id.sql +0 -0
  155. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/db/schema/0017_price_snapshots_provider_id.sql +0 -0
  156. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/db/schema/0018_provider_pings.sql +0 -0
  157. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/db/schema/0019_client_ip.sql +0 -0
  158. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/db/schema/0020_performance_indexes.sql +0 -0
  159. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/db/schema/0021_provider_model_metadata.sql +0 -0
  160. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/db/schema/0022_dashboard_indexes.sql +0 -0
  161. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/db/schema/0023_deprecated_model_placeholder.sql +0 -0
  162. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/db/schema/0024_account_backoffs.sql +0 -0
  163. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/db/schema/0025_stale_request_index.sql +0 -0
  164. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/db/schema/0026_attempt_observability.sql +0 -0
  165. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/db/schema/0027_routing_decisions.sql +0 -0
  166. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/db/schema/0028_operational_events.sql +0 -0
  167. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/db/schema/0029_latency_phases.sql +0 -0
  168. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/db/schema/0030_model_pricing_aliases.sql +0 -0
  169. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/db/schema/0031_price_snapshot_provenance.sql +0 -0
  170. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/db/schema/0032_usage_rollups.sql +0 -0
  171. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/db/schema/0033_request_provider_local_cost.sql +0 -0
  172. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/db/schema/0034_transcoding_daily.sql +0 -0
  173. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/db/schema/0035_routing_decision_score_components.sql +0 -0
  174. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/db/schema/checksums.json +0 -0
  175. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/deploy/__init__.py +0 -0
  176. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/deploy_user.py +0 -0
  177. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/errors.py +0 -0
  178. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/fastcli.py +0 -0
  179. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/health/__init__.py +0 -0
  180. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/health/backoff.py +0 -0
  181. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/health/circuit_breaker.py +0 -0
  182. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/health/health_manager.py +0 -0
  183. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/integrations/__init__.py +0 -0
  184. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/integrations/opencode.py +0 -0
  185. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/lifecycle/__init__.py +0 -0
  186. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/lifecycle/backup.py +0 -0
  187. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/lifecycle/uninstall.py +0 -0
  188. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/logging.py +0 -0
  189. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/metrics/__init__.py +0 -0
  190. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/metrics/buffer.py +0 -0
  191. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/models/__init__.py +0 -0
  192. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/models/api.py +0 -0
  193. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/models/config.py +0 -0
  194. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/models/database.py +0 -0
  195. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/models/domain.py +0 -0
  196. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/onboard.py +0 -0
  197. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/providers/__init__.py +0 -0
  198. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/providers/_templates.toml +0 -0
  199. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/providers/auth.py +0 -0
  200. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/providers/client_pool.py +0 -0
  201. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/providers/connect.py +0 -0
  202. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/providers/contract.py +0 -0
  203. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/providers/dns_cache.py +0 -0
  204. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/providers/outbound.py +0 -0
  205. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/providers/pproxy_transport.py +0 -0
  206. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/proxy/__init__.py +0 -0
  207. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/proxy/client.py +0 -0
  208. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/proxy/cost_reporting.py +0 -0
  209. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/proxy/sse_observer.py +0 -0
  210. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/proxy/usage.py +0 -0
  211. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/py.typed +0 -0
  212. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/quota/__init__.py +0 -0
  213. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/quota/audit.py +0 -0
  214. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/quota/estimation.py +0 -0
  215. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/quota/reservation.py +0 -0
  216. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/quota/scorer.py +0 -0
  217. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/request/__init__.py +0 -0
  218. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/request/attempt_finalizer.py +0 -0
  219. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/request/body.py +0 -0
  220. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/request/coordinator.py +0 -0
  221. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/request/finalizer.py +0 -0
  222. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/request/limits.py +0 -0
  223. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/retry/__init__.py +0 -0
  224. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/retry/classification.py +0 -0
  225. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/routing/__init__.py +0 -0
  226. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/routing/eligibility.py +0 -0
  227. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/routing/provider.py +0 -0
  228. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/routing/router.py +0 -0
  229. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/runtime.py +0 -0
  230. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/runtime_dispatch.py +0 -0
  231. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/runtime_metrics.py +0 -0
  232. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/runtime_paths.py +0 -0
  233. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/security/__init__.py +0 -0
  234. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/security/redaction.py +0 -0
  235. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/stats/__init__.py +0 -0
  236. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/stats/grouped_timeseries.py +0 -0
  237. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/stats/queries.py +0 -0
  238. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/stats/service.py +0 -0
  239. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/toml_edit.py +0 -0
  240. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/transcoder/__init__.py +0 -0
  241. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/transcoder/anthropic_to_openai.py +0 -0
  242. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/transcoder/context.py +0 -0
  243. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/transcoder/errors.py +0 -0
  244. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/transcoder/ids.py +0 -0
  245. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/transcoder/openai_to_anthropic.py +0 -0
  246. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/transcoder/policy.py +0 -0
  247. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/transcoder/protocol.py +0 -0
  248. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/transcoder/static_headers.py +0 -0
  249. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/transcoder/streaming.py +0 -0
  250. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/transcoder/usage.py +0 -0
  251. {eggpool-0.3.7 → eggpool-0.3.8}/src/eggpool/update_checker.py +0 -0
  252. {eggpool-0.3.7 → eggpool-0.3.8}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: eggpool
3
- Version: 0.3.7
3
+ Version: 0.3.8
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
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "eggpool"
3
- version = "0.3.7"
3
+ version = "0.3.8"
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"
@@ -106,6 +106,59 @@ class CatalogFetchError(RuntimeError):
106
106
  """Raised when a catalog fetch fails (network, parse, auth)."""
107
107
 
108
108
 
109
+ def _safe_parse_catalog_price_per_1k(
110
+ *,
111
+ catalog_name: str,
112
+ model_id: str,
113
+ category: str,
114
+ value: object,
115
+ default_unit: str = "1k",
116
+ ) -> float | None:
117
+ """Parse an untrusted external catalog price field.
118
+
119
+ External catalogs are advisory. A malformed or negative field should
120
+ remove that category from the resolved pricing, not fail the whole
121
+ refresh cycle or discard other valid rates from the same model row.
122
+ """
123
+ from eggpool.catalog.pricing import parse_price_per_1k
124
+
125
+ try:
126
+ return parse_price_per_1k(value, default_unit=default_unit)
127
+ except Exception as exc:
128
+ logger.warning(
129
+ "Ignoring invalid %s %s price for %s: %s",
130
+ catalog_name,
131
+ category,
132
+ model_id,
133
+ exc,
134
+ )
135
+ return None
136
+
137
+
138
+ def _safe_parse_catalog_microdollars(
139
+ *,
140
+ catalog_name: str,
141
+ model_id: str,
142
+ category: str,
143
+ value: object,
144
+ default_unit: str | None = None,
145
+ ) -> int | None:
146
+ """Parse an untrusted external catalog cache-rate field."""
147
+ from eggpool.catalog.pricing import parse_microdollars_per_million
148
+
149
+ try:
150
+ return parse_microdollars_per_million(value, default_unit=default_unit)
151
+ except Exception as exc:
152
+ logger.warning(
153
+ "Ignoring invalid %s %s price for %s: %s",
154
+ catalog_name,
155
+ category,
156
+ model_id,
157
+ exc,
158
+ )
159
+ return None
160
+
161
+
109
162
  class CatalogHttpClient(Protocol):
110
163
  """Minimal async HTTP client interface used by catalog resolvers."""
111
164
 
@@ -224,8 +277,13 @@ class OpenRouterCatalogResolver:
224
277
  payload_obj: object = response.json()
225
278
  except (httpx.HTTPError, ValueError) as exc:
226
279
  raise CatalogFetchError(f"OpenRouter fetch failed: {exc}") from exc
227
- entries = self._parse_catalog(payload_obj)
228
- self._cache.store(entries)
280
+ try:
281
+ entries = self._parse_catalog(payload_obj)
282
+ self._cache.store(entries)
283
+ except Exception as exc:
284
+ raise CatalogFetchError(
285
+ f"OpenRouter catalog parse failed: {exc}"
286
+ ) from exc
229
287
  return entries
230
288
 
231
289
  @staticmethod
@@ -249,8 +307,13 @@ class OpenRouterCatalogResolver:
249
307
  entry = OpenRouterCatalogResolver._parse_entry(
250
308
  model_id_obj, pricing_obj, raw_dict
251
309
  )
252
- except (ValueError, TypeError) as exc:
253
- logger.warning("Skipping catalog entry %r: %s", model_id_obj, exc)
310
+ except Exception as exc:
311
+ logger.warning(
312
+ "Skipping catalog entry %r after unexpected parse failure: %s",
313
+ model_id_obj,
314
+ exc,
315
+ exc_info=True,
316
+ )
254
317
  continue
255
318
  entries[model_id_obj] = entry
256
319
  # Strip raw upstream JSON to bound the cache footprint;
@@ -264,27 +327,40 @@ class OpenRouterCatalogResolver:
264
327
  model_id: str, pricing: object, raw: dict[str, Any]
265
328
  ) -> CatalogEntry:
266
329
  """Translate an OpenRouter pricing block into a CatalogEntry."""
267
- from eggpool.catalog.pricing import (
268
- parse_microdollars_per_million,
269
- parse_price_per_1k,
270
- )
271
330
 
272
331
  def _opt(key: str) -> object | None:
273
332
  if not isinstance(pricing, dict):
274
333
  return None
275
- value: object = pricing.get(key) # type: ignore[reportUnknownMemberType]
276
- if isinstance(value, (str, int, float)):
277
- return value
278
- return None
334
+ return pricing.get(key) # type: ignore[reportUnknownMemberType]
279
335
 
280
336
  # OpenRouter fields are dollars-per-token numeric strings.
281
- input_per_1k = parse_price_per_1k(_opt("prompt"), default_unit="token")
282
- output_per_1k = parse_price_per_1k(_opt("completion"), default_unit="token")
283
- cache_read = parse_microdollars_per_million(
284
- _opt("input_cache_read"), default_unit="token"
337
+ input_per_1k = _safe_parse_catalog_price_per_1k(
338
+ catalog_name=OpenRouterCatalogResolver.name,
339
+ model_id=model_id,
340
+ category="input",
341
+ value=_opt("prompt"),
342
+ default_unit="token",
343
+ )
344
+ output_per_1k = _safe_parse_catalog_price_per_1k(
345
+ catalog_name=OpenRouterCatalogResolver.name,
346
+ model_id=model_id,
347
+ category="output",
348
+ value=_opt("completion"),
349
+ default_unit="token",
350
+ )
351
+ cache_read = _safe_parse_catalog_microdollars(
352
+ catalog_name=OpenRouterCatalogResolver.name,
353
+ model_id=model_id,
354
+ category="cache_read",
355
+ value=_opt("input_cache_read"),
356
+ default_unit="token",
285
357
  )
286
- cache_write = parse_microdollars_per_million(
287
- _opt("input_cache_write"), default_unit="token"
358
+ cache_write = _safe_parse_catalog_microdollars(
359
+ catalog_name=OpenRouterCatalogResolver.name,
360
+ model_id=model_id,
361
+ category="cache_write",
362
+ value=_opt("input_cache_write"),
363
+ default_unit="token",
288
364
  )
289
365
  return CatalogEntry(
290
366
  catalog_model_id=model_id,
@@ -375,6 +451,15 @@ class CatalogResolverPipeline:
375
451
  exc,
376
452
  )
377
453
  continue
454
+ except Exception as exc:
455
+ logger.exception(
456
+ "Catalog %s failed unexpectedly for %s/%s: %s",
457
+ resolver.name,
458
+ provider_id,
459
+ model_id,
460
+ exc,
461
+ )
462
+ continue
378
463
  entry = catalog.get(alias.catalog_model_id)
379
464
  if entry is None:
380
465
  logger.warning(
@@ -385,10 +470,20 @@ class CatalogResolverPipeline:
385
470
  model_id,
386
471
  )
387
472
  continue
388
- return resolver.to_resolved_pricing(
389
- entry=entry,
390
- provider_id=provider_id,
391
- model_id=model_id,
392
- alias=alias,
393
- )
473
+ try:
474
+ return resolver.to_resolved_pricing(
475
+ entry=entry,
476
+ provider_id=provider_id,
477
+ model_id=model_id,
478
+ alias=alias,
479
+ )
480
+ except Exception as exc:
481
+ logger.exception(
482
+ "Catalog %s failed to convert pricing for %s/%s: %s",
483
+ resolver.name,
484
+ provider_id,
485
+ model_id,
486
+ exc,
487
+ )
488
+ continue
394
489
  return None
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