eggpool 0.7.2__tar.gz → 0.7.3__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.
- {eggpool-0.7.2 → eggpool-0.7.3}/AGENTS.md +3 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/CHANGELOG.md +36 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/PKG-INFO +1 -1
- {eggpool-0.7.2 → eggpool-0.7.3}/architecture/deep-dive-health.md +19 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/architecture/deep-dive-providers.md +10 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/architecture/deep-dive-request-lifecycle.md +50 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/architecture/deep-dive-retry.md +5 -1
- {eggpool-0.7.2 → eggpool-0.7.3}/architecture/deep-dive-routing.md +12 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/pyproject.toml +1 -1
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/failure/applier.py +25 -26
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/request/coordinator.py +97 -32
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/request/provider_bound_request.py +26 -1
- {eggpool-0.7.2 → eggpool-0.7.3}/uv.lock +1 -1
- {eggpool-0.7.2 → eggpool-0.7.3}/.env.example +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/.github/workflows/ci.yml +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/.gitignore +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/LICENSE +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/README.md +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/architecture/README.md +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/architecture/deep-dive-background.md +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/architecture/deep-dive-catalog.md +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/architecture/deep-dive-control.md +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/architecture/deep-dive-core.md +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/architecture/deep-dive-dashboard.md +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/architecture/deep-dive-database.md +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/architecture/deep-dive-deployment.md +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/architecture/deep-dive-integrations.md +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/architecture/deep-dive-lifecycle.md +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/architecture/deep-dive-metrics.md +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/architecture/deep-dive-model-info.md +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/architecture/deep-dive-models.md +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/architecture/deep-dive-observability.md +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/architecture/deep-dive-runtime.md +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/architecture/deep-dive-security.md +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/architecture/deep-dive-transcoder.md +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/architecture/overview.md +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/artifacts/plan-019-evidence.md +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/artifacts/plan-020-evidence.md +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/artifacts/plan-021-evidence.md +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/artifacts/plan-023-baseline.md +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/artifacts/plan-030-exact-head-evidence.md +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/config-examples/claude-code.env +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/config-examples/opencode.jsonc +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/config.example.toml +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/config.sbc.example.toml +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/deploy/eggpool-logrotate.conf +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/deploy/eggpool.service +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/deploy/env.example +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/docs/agent-configuration.md +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/docs/api-reference.md +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/docs/backup-restore.md +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/docs/config-profiles.md +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/docs/deployment.md +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/docs/filesystem-layout.md +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/docs/firewall.md +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/docs/live-config-rehash.md +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/docs/model-info-openrouter-debug.md +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/docs/model-limits.md +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/docs/network-diagnostics.md +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/docs/opencode-stream-stability.md +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/docs/operations/dispatch-stability.md +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/docs/providers.md +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/docs/proxy.md +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/docs/raspberry-pi.md +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/docs/releasing.md +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/docs/runbooks/database-recovery.md +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/docs/stateless-responses.md +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/docs/thinking.md +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/docs/transcoding.md +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/scripts/__init__.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/scripts/admission_race_stress.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/scripts/bench_sqlite_writepath.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/scripts/check_database.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/scripts/debug_model_info_openrouter.sh +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/scripts/install.sh +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/scripts/install_prompt.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/scripts/repro_high_concurrency_streams.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/scripts/run_tests_with_timeout.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/scripts/smoke_test.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/scripts/test_model_info_identity.sh +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/scripts/validate_routing.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/scripts/verify_upstream_auth.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/__init__.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/__main__.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/_share/.env.example +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/_share/config.example.toml +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/_share/config.sbc.example.toml +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/accounts/__init__.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/accounts/registry.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/accounts/state.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/api/__init__.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/api/backoff.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/api/chat_completions.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/api/errors.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/api/messages.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/api/model_info.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/api/models.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/api/network.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/api/proxy_request.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/api/responses.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/api/runtime.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/api/stats.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/api/update.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/app.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/auth.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/background/__init__.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/background/backup.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/background/cleanup.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/background/maintenance.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/catalog/__init__.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/catalog/_time.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/catalog/cache.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/catalog/capabilities.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/catalog/catalog_resolvers.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/catalog/fetcher.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/catalog/limits.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/catalog/models_dev.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/catalog/normalizer.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/catalog/pricing.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/catalog/pricing_aliases.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/catalog/pricing_resolver.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/catalog/protocols.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/catalog/service.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/cli.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/cli_exit_codes.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/cli_full.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/cli_rehash_format.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/cli_rehash_helper.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/config.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/config_reload_policy.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/config_utils.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/config_validation.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/constants.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/control/__init__.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/control/accepted_finalization.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/control/client.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/control/reload_manager.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/control/server.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/cost_recompute.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/cost_repair.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/dashboard/__init__.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/dashboard/_resources.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/dashboard/escape.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/dashboard/render.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/dashboard/routes.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/dashboard/static/chart.umd.min.js +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/dashboard/static/dashboard.css +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/dashboard/static/dashboard.js +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/dashboard/static/favicon.svg +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/dashboard/telemetry.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/dashboard/theme.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/dashboard/themes/Booberry.toml +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/dashboard/themes/Catppuccin Latte.toml +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/dashboard/themes/Catppuccin Macchiato.toml +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/dashboard/themes/Catppuccin Mocha.toml +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/dashboard/themes/Cyber Red.toml +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/dashboard/themes/Cyberpunk.toml +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/dashboard/themes/Dark Green.toml +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/dashboard/themes/Discord (80_ Saturation).toml +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/dashboard/themes/Discord.toml +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/dashboard/themes/Dracula.toml +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/dashboard/themes/Ferra Light.toml +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/dashboard/themes/Flexor Dark.toml +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/dashboard/themes/Gruvbox.toml +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/dashboard/themes/Halcyon Dark.toml +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/dashboard/themes/IntelliJ Light.toml +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/dashboard/themes/Kanagawa.toml +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/dashboard/themes/Macaw Dark.toml +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/dashboard/themes/Macaw Light.toml +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/dashboard/themes/Matrix.toml +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/dashboard/themes/Noctis Lilac.toml +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/dashboard/themes/Nord.toml +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/dashboard/themes/Nostromo Terminal.toml +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/dashboard/themes/One Dark.toml +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/dashboard/themes/Oxocarbon.toml +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/dashboard/themes/Rose Pine Dawn.toml +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/dashboard/themes/Rose Pine Moon.toml +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/dashboard/themes/Rose Pine.toml +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/dashboard/themes/Solarized Dark.toml +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/dashboard/themes/Sonokai.toml +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/dashboard/themes/Tokyo Night Storm.toml +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/dashboard/themes/VESPER.toml +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/dashboard/themes/Zenburn.toml +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/dashboard/themes/acton.toml +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/dashboard/themes/bam.toml +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/dashboard/themes/base16-atelier-forest-light.toml +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/dashboard/themes/berlin.toml +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/dashboard/themes/black but with important highlights.toml +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/dashboard/themes/broc.toml +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/dashboard/themes/cork.toml +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/dashboard/themes/ferra.toml +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/dashboard/themes/forest.toml +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/dashboard/themes/lisbon.toml +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/dashboard/themes/midnight.toml +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/dashboard/themes/oslo.toml +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/dashboard/themes/plum.toml +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/dashboard/themes/portland.toml +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/dashboard/themes/sunset.toml +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/dashboard/themes/tofino.toml +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/dashboard/themes/vanimo.toml +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/dashboard/themes/vik.toml +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/dashboard/timeseries_buckets.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/db/__init__.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/db/connection.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/db/migrations.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/db/repositories.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/db/rollup_repository.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/db/schema/0001_initial.sql +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/db/schema/0002_indexes.sql +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/db/schema/0003_request_attempts.sql +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/db/schema/0004_integration_hardening.sql +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/db/schema/0005_price_microdollars.sql +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/db/schema/0006_correct_price_microdollars.sql +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/db/schema/0007_price_cache_rates.sql +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/db/schema/0008_proxy_request_identity.sql +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/db/schema/0009_model_protocol_source.sql +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/db/schema/0010_health_probe.sql +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/db/schema/0011_model_resolution_status.sql +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/db/schema/0012_drop_reservations_estimated_microdollars.sql +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/db/schema/0013_request_attempts_account_id_index.sql +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/db/schema/0014_bandwidth_tracking.sql +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/db/schema/0015_multi_provider.sql +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/db/schema/0016_requests_provider_id.sql +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/db/schema/0017_price_snapshots_provider_id.sql +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/db/schema/0018_provider_pings.sql +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/db/schema/0019_client_ip.sql +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/db/schema/0020_performance_indexes.sql +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/db/schema/0021_provider_model_metadata.sql +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/db/schema/0022_dashboard_indexes.sql +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/db/schema/0023_deprecated_model_placeholder.sql +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/db/schema/0024_account_backoffs.sql +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/db/schema/0025_stale_request_index.sql +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/db/schema/0026_attempt_observability.sql +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/db/schema/0027_routing_decisions.sql +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/db/schema/0028_operational_events.sql +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/db/schema/0029_latency_phases.sql +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/db/schema/0030_model_pricing_aliases.sql +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/db/schema/0031_price_snapshot_provenance.sql +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/db/schema/0032_usage_rollups.sql +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/db/schema/0033_request_provider_local_cost.sql +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/db/schema/0034_transcoding_daily.sql +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/db/schema/0035_routing_decision_score_components.sql +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/db/schema/0036_model_info.sql +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/db/schema/0037_model_info_failure_count.sql +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/db/schema/0038_model_info_phase5.sql +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/db/schema/0039_thinking_observability.sql +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/db/schema/0040_cache_token_observability.sql +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/db/schema/0041_canonical_request_segmentation.sql +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/db/schema/0042_observe_mode_compression_accounting.sql +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/db/schema/0043_safe_suffix_compression.sql +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/db/schema/0044_compression_policy_resolver.sql +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/db/schema/0045_synthetic_cache_controls.sql +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/db/schema/0046_closed_loop_threshold_tuning.sql +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/db/schema/0047_normalize_rollup_bucket_start.sql +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/db/schema/0048_request_cost_repairs.sql +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/db/schema/0049_model_info_match_evidence.sql +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/db/schema/0050_routing_decisions_retention_index.sql +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/db/schema/0051_model_quarantine.sql +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/db/schema/0052_catalog_refresh_state.sql +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/db/schema/0053_remove_attempt_status_analytics_index.sql +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/db/schema/0054_model_quarantine_null_identity.sql +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/db/schema/checksums.json +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/deploy/__init__.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/deploy_user.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/errors.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/event_loop_lag.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/failure/__init__.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/failure/classifier.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/failure/effects.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/failure/observation.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/failure/quarantine.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/failure/signal.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/failure/signal_extract.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/fastcli.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/generation_factory.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/health/__init__.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/health/backoff.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/health/circuit_breaker.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/health/health_manager.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/health/writable_probe.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/integrations/__init__.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/integrations/aider.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/integrations/cline.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/integrations/codex.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/integrations/common.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/integrations/continue_dev.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/integrations/goose.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/integrations/kilo.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/integrations/opencode.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/integrations/openhands.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/integrations/qwen_code.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/integrations/roo_code.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/jsonx.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/lifecycle/__init__.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/lifecycle/backup.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/lifecycle/uninstall.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/logging.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/metrics/__init__.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/metrics/buffer.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/metrics/failure_effects.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/metrics/thinking.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/model_info/__init__.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/model_info/dedup.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/model_info/identity.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/model_info/matching.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/model_info/normalization.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/model_info/presentation.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/model_info/repository.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/model_info/scheduler.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/model_info/service.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/model_info/sources/__init__.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/model_info/sources/artificial_analysis.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/model_info/sources/base.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/model_info/sources/huggingface.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/model_info/sources/openrouter.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/model_info/sources/provider_catalog.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/model_info/types.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/models/__init__.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/models/api.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/models/config.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/models/database.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/models/domain.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/observability/__init__.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/observability/routing_trace_writer.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/onboard.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/providers/__init__.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/providers/_templates.toml +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/providers/auth.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/providers/client_pool.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/providers/connect.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/providers/contract.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/providers/outbound.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/providers/pproxy_transport.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/proxy/__init__.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/proxy/client.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/proxy/cost_reporting.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/proxy/normalized_usage.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/proxy/sse.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/proxy/sse_observer.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/proxy/usage.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/py.typed +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/quota/__init__.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/quota/audit.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/quota/estimation.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/quota/reservation.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/quota/scorer.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/reload_diagnostics.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/reload_transaction.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/request/__init__.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/request/attempt_finalizer.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/request/backoff_persistence.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/request/body.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/request/claim_lifecycle.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/request/failure_helpers.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/request/finalization_job.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/request/finalizer.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/request/limits.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/request/parsed_payload.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/request/parsed_upstream_response.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/request/payload_utils.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/request/response_handoff.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/request/routing_helpers.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/request/routing_trace_guard.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/request/selection_claim_diagnostics.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/request/static_helpers.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/request/stream_completion.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/request/stream_diagnostics.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/request/terminal_status.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/request/thinking_adaptation.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/request/transform_pipeline.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/request/upstream_execution.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/request/upstream_helpers.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/request/usage_helpers.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/retry/__init__.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/retry/classification.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/routing/__init__.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/routing/config.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/routing/eligibility.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/routing/fairness.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/routing/provider.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/routing/router.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/runtime.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/runtime_dispatch.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/runtime_manager.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/runtime_metrics.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/runtime_paths.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/runtime_task_inventory.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/runtime_tasks.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/security/__init__.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/security/redaction.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/stats/__init__.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/stats/cache_metrics.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/stats/dashboard_explain.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/stats/grouped_timeseries.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/stats/queries.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/stats/segmentation.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/stats/service.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/stats/transcoding.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/toml_edit.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/transcoder/__init__.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/transcoder/anthropic_to_openai.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/transcoder/budget_resolver.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/transcoder/builtin_contracts.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/transcoder/cache_stability.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/transcoder/cache_translation.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/transcoder/context.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/transcoder/errors.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/transcoder/ids.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/transcoder/json_helpers.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/transcoder/openai_to_anthropic.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/transcoder/policy.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/transcoder/prepared.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/transcoder/protocol.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/transcoder/provider_adaptation.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/transcoder/sensitive_media.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/transcoder/static_headers.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/transcoder/streaming.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/transcoder/usage.py +0 -0
- {eggpool-0.7.2 → eggpool-0.7.3}/src/eggpool/update_checker.py +0 -0
|
@@ -147,6 +147,9 @@ Non-obvious wiring:
|
|
|
147
147
|
- **`static_models` is source of truth for provider-specific protocol**: providers serving non-default protocols must ship `[[providers.<id>.static_models]]` rows
|
|
148
148
|
- **No pre-commit hooks configured**: CI runs ruff, pyright, and pytest via GitHub Actions
|
|
149
149
|
- **When constructing `RequestCoordinator` in tests**: pass an explicit `transcoder_policy` or assert the desired default
|
|
150
|
+
- **`ProviderBoundRequest` dispatch-freeze**: `serialize_provider_payload()` freezes the body; `replace_provider_payload()` and `set_provider_payload(increment_generation=False)` reject when frozen. Only generation-incrementing methods (`set_provider_payload(increment_generation=True)`, `adopt_provider_payload(increment_generation=True)`) clear the freeze — the post-selection transcoder relies on this to replace a previously dispatched body on retry
|
|
151
|
+
- **Thinking rejection error class**: `CapabilityError` (400) only when the aggregated thinking status is genuinely `unknown` or `unsupported`. When all supporting accounts are quarantined but the provider entry reports `supported`/`mixed`, a transient 503/502 is raised instead. Aggregation iterates `cache.get_provider_model_entries()` (which applies overrides), not `cache.get_model()` (which does not). See `RequestCoordinator._determine_thinking_rejection_status` and `architecture/deep-dive-request-lifecycle.md`
|
|
152
|
+
- **Per-model quarantine suppresses account-wide circuit breaker**: when `effects.model_effect != "none"` (quarantine), `EffectsApplier._apply_account_effect` skips `HealthManager.record_failure()` for that account. The account-wide breaker advances only when the classifier sets `source="transport"` (genuine account-wide failure: DNS, TLS, persistent transport failure with no per-model cause). A per-model 5xx must quarantine the `(account, model)` pair, not the whole account. See `architecture/deep-dive-health.md`
|
|
150
153
|
|
|
151
154
|
## Error Handling
|
|
152
155
|
|
|
@@ -36,6 +36,42 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
36
36
|
no-account-disable path for keyword false-positives in client-error bodies,
|
|
37
37
|
5xx cooldown non-extension to siblings, and applier resilience under partial
|
|
38
38
|
side-effect failure.
|
|
39
|
+
- **muse-spark-1.2-contributor routing fix.** Three coordinated changes
|
|
40
|
+
restore the canonical ``OpenCode Go`` Muse Spark request path and stop
|
|
41
|
+
one model's failure from black-holing sibling models on the same
|
|
42
|
+
subscription:
|
|
43
|
+
|
|
44
|
+
1. `ProviderBoundRequest.set_provider_payload` and
|
|
45
|
+
`adopt_provider_payload` now clear the dispatch-freeze flag when a new
|
|
46
|
+
generation begins. Pre-fix, the post-selection transcoder's
|
|
47
|
+
`adopt_provider_payload` raised `RuntimeError: provider payload is
|
|
48
|
+
frozen` after the first attempt's serialization, breaking every retry
|
|
49
|
+
against a different selected provider.
|
|
50
|
+
|
|
51
|
+
2. `RequestCoordinator._determine_thinking_rejection_status` now
|
|
52
|
+
aggregates per-provider capability overrides when the collapsed
|
|
53
|
+
entry reports `unknown`. Built-in overrides (e.g. the canonical
|
|
54
|
+
OpenCode Go host capabilities for `muse-spark-1.2-contributor`) live
|
|
55
|
+
in the provider-scoped cache row, so the previous bare-model lookup
|
|
56
|
+
missed them and surfaced a misleading client-validation 400. The
|
|
57
|
+
capability-error path now requires `rejected_status` to be truly
|
|
58
|
+
`unknown`/`unsupported` before surfacing the 400; otherwise the
|
|
59
|
+
router falls through to a transient `No accounts available` (503).
|
|
60
|
+
|
|
61
|
+
3. `EffectsApplier._apply_account_effect` now skips
|
|
62
|
+
`HealthManager.record_failure` when the classifier set
|
|
63
|
+
`model_effect="quarantine"` — the per-model disable is the only
|
|
64
|
+
shared-state penalty in that case. Pre-fix, a single muse-spark 5xx
|
|
65
|
+
per account advanced the account-wide circuit breaker so five
|
|
66
|
+
per-model 5xxes tripped the breaker for ALL models on the same
|
|
67
|
+
subscription. Post-fix, sibling models on the same opencode-go
|
|
68
|
+
account keep routing while only muse-spark-1.2-contributor is
|
|
69
|
+
quarantined for the bounded TTL. Tests:
|
|
70
|
+
`tests/integration/test_muse_spark_live_e2e.py` (3 tests covering the
|
|
71
|
+
end-to-end live routing path with thinking controls and sibling-model
|
|
72
|
+
isolation), `tests/integration/test_muse_spark_capability_status_attribution.py`
|
|
73
|
+
(catalog + status attribution), and `tests/unit/test_provider_bound_request.py`
|
|
74
|
+
+ `tests/unit/test_effects_idempotency.py` (per-fix unit coverage).
|
|
39
75
|
|
|
40
76
|
### Added
|
|
41
77
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: eggpool
|
|
3
|
-
Version: 0.7.
|
|
3
|
+
Version: 0.7.3
|
|
4
4
|
Summary: A lightweight proxy that aggregates multiple LLM provider accounts behind an OpenAI Chat Completions-compatible endpoint
|
|
5
5
|
Project-URL: Homepage, https://github.com/eggstack/eggpool
|
|
6
6
|
Project-URL: Repository, https://github.com/eggstack/eggpool
|
|
@@ -126,6 +126,24 @@ records the circuit failure; the effects applier never records that same
|
|
|
126
126
|
transition a second time. Request-local errors and cancellation release a
|
|
127
127
|
half-open probe without provider penalties.
|
|
128
128
|
|
|
129
|
+
### Per-model quarantine suppresses account-wide circuit advance
|
|
130
|
+
|
|
131
|
+
When the classifier sets `model_effect = "quarantine"` on a 5xx, the
|
|
132
|
+
effects applier (`EffectsApplier._apply_account_effect`) skips the
|
|
133
|
+
`HealthManager.record_failure()` call for that account. The per-model
|
|
134
|
+
disable (`disable_model`) is the **sole** shared-state penalty in that
|
|
135
|
+
case; the account-wide circuit breaker stays closed. The breaker
|
|
136
|
+
advances only when the classifier sets `source = "transport"`
|
|
137
|
+
(genuine account-wide failure: DNS failure, TLS error, persistent 503
|
|
138
|
+
with no model-specific cause) **and** `model_effect = "none"`.
|
|
139
|
+
|
|
140
|
+
This isolation prevents N per-model 5xx failures from tripping the
|
|
141
|
+
breaker for all models on the same subscription. A single model's
|
|
142
|
+
upstream anomaly must not black-hole sibling models on the same
|
|
143
|
+
account. The `effects.account_effect` is still `"failure"` in the
|
|
144
|
+
quarantined case; the `model_effect` flag gates whether the breaker
|
|
145
|
+
call fires.
|
|
146
|
+
|
|
129
147
|
## Key Invariants
|
|
130
148
|
|
|
131
149
|
- Health driven solely by upstream-observed failures, operator disablement, and catalog/protocol incompatibility
|
|
@@ -138,3 +156,4 @@ half-open probe without provider penalties.
|
|
|
138
156
|
- Half-open probe acquisition always converges through success, failure, cancellation, or local release
|
|
139
157
|
- Cooldown timers are monotonic
|
|
140
158
|
- `AccountHealth` fields: `consecutive_failures`, `disabled_models`, `disabled_until`, `disabled_reason`, `cooldown_until`
|
|
159
|
+
- Per-model quarantine (`model_effect != "none"`) is the SOLE shared-state penalty; the account-wide circuit breaker advances only when `source="transport"` AND `model_effect="none"` (genuine account-wide failure). A single model's 5xx must not black-hole sibling models on the same account
|
|
@@ -50,3 +50,13 @@ truth when a provider serves a non-default protocol or capability contract.
|
|
|
50
50
|
provider's capability row. Speculative universal ceilings (such as a
|
|
51
51
|
universal 5 MiB local-runtime ceiling) are not encoded in bundled templates;
|
|
52
52
|
only verified provider-defined limits are advertised.
|
|
53
|
+
- Per-provider capability overrides (e.g. `thinking.status`) live in the
|
|
54
|
+
provider-scoped cache row and are applied by
|
|
55
|
+
`ModelCatalogCache.get_provider_model_entry()` /
|
|
56
|
+
`ModelCatalogCache.get_provider_model_entries()`. The collapsed `models`
|
|
57
|
+
row (`get_model()`) deliberately does **not** apply overrides — it
|
|
58
|
+
represents the raw catalog state. Capability rejection attribution must
|
|
59
|
+
consult provider-scoped entries, not just the collapsed row, to avoid
|
|
60
|
+
false `"unknown"` readings when overrides are present. Quarantine does
|
|
61
|
+
**not** erase a provider's capability — quarantined entries still
|
|
62
|
+
contribute to the aggregated status.
|
|
@@ -192,6 +192,19 @@ re-raising.
|
|
|
192
192
|
- `recompute_thinking_budget_for_provider()` — re-resolves budget against selected provider's capability
|
|
193
193
|
- `adapt_provider_thinking_controls()` — validates and adapts controls against the provider contract
|
|
194
194
|
|
|
195
|
+
`_determine_thinking_rejection_status()` (coordinator) — attributes a
|
|
196
|
+
thinking rejection to an aggregated capability status when all
|
|
197
|
+
eligible accounts are filtered out. Consults the collapsed
|
|
198
|
+
`models` row first, then falls back to the provider-scoped row when
|
|
199
|
+
`context.provider_id` is known, and otherwise iterates every
|
|
200
|
+
provider entry returned by `cache.get_provider_model_entries()` —
|
|
201
|
+
including quarantined accounts — and aggregates the most permissive
|
|
202
|
+
status. Most-permissive order: `supported` > `mixed` >
|
|
203
|
+
`unsupported` > `unknown`. Returns `"unknown"` or `"unsupported"`
|
|
204
|
+
only when the aggregated status is genuinely authoritative;
|
|
205
|
+
otherwise returns `None` so the caller falls through to the
|
|
206
|
+
generic transient `no_eligible_providers` reason.
|
|
207
|
+
|
|
195
208
|
### `request/upstream_helpers.py` — Upstream URL and endpoint validation
|
|
196
209
|
|
|
197
210
|
Extracted from `RequestCoordinator` in Plan 136 Phase 5. Resolves the absolute
|
|
@@ -299,6 +312,42 @@ graph afterward. `replace_provider_payload()` remains as a conservative
|
|
|
299
312
|
conditional ownership primitive for compatibility callers; the former
|
|
300
313
|
`provider_payload_copy()` transcode helper was removed in Plan 124.
|
|
301
314
|
|
|
315
|
+
### Dispatch-freeze lifecycle
|
|
316
|
+
|
|
317
|
+
`serialize_provider_payload()` serializes the current generation and
|
|
318
|
+
sets a dispatch-freeze flag (`_frozen`). Once frozen, mutations that
|
|
319
|
+
do **not** begin a new generation — `replace_provider_payload()` and
|
|
320
|
+
`set_provider_payload(increment_generation=False)` — raise
|
|
321
|
+
`RuntimeError("provider payload is frozen")` because they cannot
|
|
322
|
+
safely overwrite a body that downstream dispatch already consumed.
|
|
323
|
+
|
|
324
|
+
Methods that **begin a new generation** — `set_provider_payload(increment_generation=True)` and `adopt_provider_payload(increment_generation=True)` — reset `_frozen` alongside the cached serialized-bytes. The new generation is the canonical provider payload, and the next `serialize_provider_payload()` call re-encodes from scratch. This is what allows the post-selection cross-protocol transcoder (`_apply_selected_provider_transcode`) to replace a body that the previous attempt already serialized and dispatched — a retry that selects a different provider must rebuild from the original client payload, but the transcoder may also need to replace the previously adopted transcode result when account failover picks a different upstream. `adopt_provider_payload(increment_generation=False)` still raises when
|
|
325
|
+
frozen: it does not begin a new generation.
|
|
326
|
+
|
|
327
|
+
### Thinking rejection attribution
|
|
328
|
+
|
|
329
|
+
When all eligible accounts are filtered out (including quarantine) and
|
|
330
|
+
the request carries thinking controls,
|
|
331
|
+
`_determine_thinking_rejection_status()` attributes the rejection to a
|
|
332
|
+
capability status. Per-provider thinking overrides (e.g. the bundled
|
|
333
|
+
OpenCode Go host capabilities for `muse-spark-1.2-contributor`)
|
|
334
|
+
live in the provider-scoped cache row, **not** the collapsed
|
|
335
|
+
`models` row. `cache.get_model()` deliberately does **not** apply
|
|
336
|
+
overrides; `cache.get_provider_model_entry()` and
|
|
337
|
+
`cache.get_provider_model_entries()` do.
|
|
338
|
+
|
|
339
|
+
When `context.provider_id` is unset, the method iterates every
|
|
340
|
+
provider entry for the model and aggregates the most permissive
|
|
341
|
+
status. Quarantine does **not** erase a provider's capability —
|
|
342
|
+
quarantined entries still contribute to the aggregated status. A
|
|
343
|
+
400 (`CapabilityError`) is surfaced only when the aggregated status
|
|
344
|
+
is genuinely `unknown` or `unsupported`; when the status is
|
|
345
|
+
`supported` or `mixed` but every supporting account is currently
|
|
346
|
+
quarantined, the caller falls through to `ModelUnavailableError`
|
|
347
|
+
(503) / `UpstreamExhaustedError` so a transient retry is possible.
|
|
348
|
+
This prevents a misleading `thinking capability status: unknown`
|
|
349
|
+
400 from masking a recoverable quarantine-state failure.
|
|
350
|
+
|
|
302
351
|
Prepared transcode results retain one request-local translated JSON generation
|
|
303
352
|
without recursively freezing or rematerializing it. Valid unchanged reuse
|
|
304
353
|
adopts that generation through `adopt_provider_payload()` and attaches the
|
|
@@ -463,3 +512,4 @@ Streaming usage accumulation across chunks.
|
|
|
463
512
|
- Same URL composition rules for catalog fetch and chat dispatch
|
|
464
513
|
- Selection-claim lock splits DB I/O from runtime publication (Milestone B)
|
|
465
514
|
- Dispatch persistence is one direct per-request transaction
|
|
515
|
+
- `ProviderBoundRequest` dispatch-freeze flag resets together with `payload_generation`; mutations that do not start a new generation (`replace_provider_payload`, `set_provider_payload(increment_generation=False)`, `adopt_provider_payload(increment_generation=False)`) reject when frozen. The post-selection transcoder relies on the generation-incrementing methods to replace a previously dispatched body on retry
|
|
@@ -76,7 +76,11 @@ Upstream HTTP response
|
|
|
76
76
|
→ RetryClassifier().classify(status_code, headers, body)
|
|
77
77
|
→ RetryableError(category, retry_after)
|
|
78
78
|
→ RequestCoordinator._should_retry()
|
|
79
|
-
→
|
|
79
|
+
→ EffectsApplier.apply_once()
|
|
80
|
+
- model_effect="quarantine": disable_model only;
|
|
81
|
+
record_failure() skipped (per-model failure isolation)
|
|
82
|
+
- source="transport" + model_effect="none":
|
|
83
|
+
record_failure() advances account-wide breaker
|
|
80
84
|
→ Retry with excluded accounts
|
|
81
85
|
```
|
|
82
86
|
|
|
@@ -185,6 +185,18 @@ Authentication failure and authoritative catalog withdrawal are separate
|
|
|
185
185
|
terminal gates; they recover only through corrected credentials/operator action
|
|
186
186
|
or authoritative model reappearance.
|
|
187
187
|
|
|
188
|
+
When all eligible accounts are excluded (including quarantine) and the
|
|
189
|
+
request carries thinking controls, the error class depends on the
|
|
190
|
+
aggregated capability status across every provider entry for the model,
|
|
191
|
+
not just the collapsed row. A 400 (`CapabilityError`) is returned only
|
|
192
|
+
when the aggregated status is genuinely `unknown` or `unsupported`.
|
|
193
|
+
When the aggregated status is `supported` or `mixed` but every
|
|
194
|
+
supporting account is quarantined, a transient 502/503 (`UpstreamError`,
|
|
195
|
+
`ModelUnavailableError`) is returned so the client can retry. This
|
|
196
|
+
prevents a misleading `thinking capability status: unknown` 400 from
|
|
197
|
+
being surfaced when the underlying provider does support the request
|
|
198
|
+
but is currently unhealthy across every account.
|
|
199
|
+
|
|
188
200
|
## Score Components
|
|
189
201
|
|
|
190
202
|
Every `routing_decisions` row carries `score_components_json`:
|
|
@@ -265,32 +265,31 @@ class EffectsApplier:
|
|
|
265
265
|
self._health_manager.record_rate_limit(account, retry_after)
|
|
266
266
|
self._health_manager.release_request(account)
|
|
267
267
|
elif effects.account_effect == "failure":
|
|
268
|
-
#
|
|
269
|
-
#
|
|
270
|
-
#
|
|
271
|
-
#
|
|
272
|
-
#
|
|
273
|
-
#
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
and effects.backoff_reason
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
health.is_healthy = False
|
|
268
|
+
# Per-model failures (``model_effect = "quarantine"``) must
|
|
269
|
+
# never advance the account-wide circuit breaker: a single
|
|
270
|
+
# model/provider anomaly should not black-hole sibling
|
|
271
|
+
# models on the same account. The per-model disable applied
|
|
272
|
+
# via ``_apply_model_effect`` is the only shared-state
|
|
273
|
+
# penalty in that case. Only when the failure is genuinely
|
|
274
|
+
# account-wide (no per-model suppression requested) do we
|
|
275
|
+
# call ``record_failure`` to advance the breaker counter.
|
|
276
|
+
if effects.model_effect == "none":
|
|
277
|
+
self._health_manager.record_failure(
|
|
278
|
+
account,
|
|
279
|
+
model_id=obs.model_id,
|
|
280
|
+
reason=effects.backoff_reason or "unknown",
|
|
281
|
+
)
|
|
282
|
+
if effects.backoff_until and effects.backoff_reason:
|
|
283
|
+
# Legacy/fallback path: no per-model suppression was
|
|
284
|
+
# requested, so fall back to the previous account-wide
|
|
285
|
+
# bounded cooldown. This branch only fires for callers
|
|
286
|
+
# that opt into account-only failure handling.
|
|
287
|
+
delay = effects.backoff_until - now
|
|
288
|
+
if delay > 0:
|
|
289
|
+
health = self._health_manager.get_account_health(account)
|
|
290
|
+
health.cooldown_until = self._health_manager.clock() + delay
|
|
291
|
+
health.health_state = "cooldown"
|
|
292
|
+
health.is_healthy = False
|
|
294
293
|
elif effects.account_effect == "cooldown":
|
|
295
294
|
self._health_manager.record_failure(
|
|
296
295
|
account,
|
|
@@ -2251,34 +2251,61 @@ class RequestCoordinator:
|
|
|
2251
2251
|
context=context,
|
|
2252
2252
|
thinking_req=thinking_req,
|
|
2253
2253
|
)
|
|
2254
|
-
|
|
2255
|
-
|
|
2254
|
+
# ``rejected_status`` is ``"unknown"`` or
|
|
2255
|
+
# ``"unsupported"`` when the capability row is
|
|
2256
|
+
# truly authoritative (built-in override plus any
|
|
2257
|
+
# provider-scoped row report the same status);
|
|
2258
|
+
# ``None`` means every supporting provider has been
|
|
2259
|
+
# quarantined or filtered for reasons unrelated to
|
|
2260
|
+
# the thinking capability — the underlying provider
|
|
2261
|
+
# still supports thinking, so do not surface a
|
|
2262
|
+
# misleading client-validation 400. Fall through to
|
|
2263
|
+
# the standard ``UpstreamExhaustedError`` /
|
|
2264
|
+
# ``ModelUnavailableError`` path so the operator
|
|
2265
|
+
# observes a transient upstream unavailability.
|
|
2266
|
+
if rejected_status in {"unknown", "unsupported"}:
|
|
2267
|
+
if rejected_status == "unknown":
|
|
2268
|
+
await _thinking_counter.increment_unknown_capability(
|
|
2269
|
+
client_protocol=thinking_req.client_protocol,
|
|
2270
|
+
)
|
|
2271
|
+
else:
|
|
2272
|
+
await _thinking_counter.increment_unsupported_capability(
|
|
2273
|
+
client_protocol=thinking_req.client_protocol,
|
|
2274
|
+
)
|
|
2275
|
+
await _thinking_counter.increment_rejected(
|
|
2256
2276
|
client_protocol=thinking_req.client_protocol,
|
|
2277
|
+
capability_status="no_eligible_providers",
|
|
2257
2278
|
)
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2279
|
+
if context.thinking_trace is not None:
|
|
2280
|
+
context.thinking_trace["decision"] = "rejected"
|
|
2281
|
+
context.thinking_trace["capability_status"] = rejected_status
|
|
2282
|
+
raise CapabilityError(
|
|
2283
|
+
model_id=context.model_id,
|
|
2284
|
+
capability="thinking",
|
|
2285
|
+
requested_fields=thinking_req.fields,
|
|
2286
|
+
message=(
|
|
2287
|
+
f"Model {context.model_id!r} is available, "
|
|
2288
|
+
f"but no eligible provider is known to "
|
|
2289
|
+
f"support requested thinking controls "
|
|
2290
|
+
f"(thinking capability status: "
|
|
2291
|
+
f"{rejected_status or 'unknown'})."
|
|
2292
|
+
),
|
|
2261
2293
|
)
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
)
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2294
|
+
# Capability status is genuinely ``supported`` (or
|
|
2295
|
+
# ``mixed``) for the selected provider but every
|
|
2296
|
+
# supporting account is currently filtered out
|
|
2297
|
+
# (typically due to transient quarantine). Surface a
|
|
2298
|
+
# 502/503 transient unavailability so the request
|
|
2299
|
+
# can be retried after the upstream cools down.
|
|
2300
|
+
if self._all_accounts_attempted(
|
|
2301
|
+
context, capability_policy=_capability_policy
|
|
2302
|
+
):
|
|
2303
|
+
raise UpstreamExhaustedError(
|
|
2304
|
+
f"All eligible accounts attempted for model "
|
|
2305
|
+
f"{context.model_id!r}"
|
|
2270
2306
|
)
|
|
2271
|
-
raise
|
|
2272
|
-
|
|
2273
|
-
capability="thinking",
|
|
2274
|
-
requested_fields=thinking_req.fields,
|
|
2275
|
-
message=(
|
|
2276
|
-
f"Model {context.model_id!r} is available, "
|
|
2277
|
-
f"but no eligible provider is known to "
|
|
2278
|
-
f"support requested thinking controls "
|
|
2279
|
-
f"(thinking capability status: "
|
|
2280
|
-
f"{rejected_status or 'unknown'})."
|
|
2281
|
-
),
|
|
2307
|
+
raise ModelUnavailableError(
|
|
2308
|
+
f"No accounts available for model {context.model_id!r}"
|
|
2282
2309
|
)
|
|
2283
2310
|
if self._all_accounts_attempted(
|
|
2284
2311
|
context, capability_policy=_capability_policy
|
|
@@ -4539,9 +4566,17 @@ class RequestCoordinator:
|
|
|
4539
4566
|
provider-scoped thinking rows live in
|
|
4540
4567
|
``provider_model_metadata`` and are applied on the per-candidate
|
|
4541
4568
|
eligibility check but never make it into the collapsed entry.
|
|
4542
|
-
To avoid a false ``unknown`` reading that would mis-attribute a
|
|
4543
|
-
rejection, also consult the provider-scoped
|
|
4544
|
-
collapsed one reports ``unknown
|
|
4569
|
+
To avoid a false ``"unknown"`` reading that would mis-attribute a
|
|
4570
|
+
rejection, also consult the provider-scoped entries when the
|
|
4571
|
+
collapsed one reports ``"unknown"`` — first the routing
|
|
4572
|
+
``context.provider_id`` if it is set, and otherwise every
|
|
4573
|
+
provider with a known provider-scoped row. Built-in capability
|
|
4574
|
+
overrides (e.g. the canonical OpenCode Go host capabilities for
|
|
4575
|
+
``muse-spark-1.2-contributor``) are applied at request time by
|
|
4576
|
+
``ModelCatalogCache.get_provider_model_entry``; the bare-model
|
|
4577
|
+
request path therefore still resolves the correct
|
|
4578
|
+
``supported`` status even when ``provider_id`` was not parsed
|
|
4579
|
+
out of the client request.
|
|
4545
4580
|
"""
|
|
4546
4581
|
from eggpool.catalog.capabilities import extract_thinking_status_from_entry
|
|
4547
4582
|
|
|
@@ -4549,15 +4584,45 @@ class RequestCoordinator:
|
|
|
4549
4584
|
try:
|
|
4550
4585
|
cache = self._catalog.cache
|
|
4551
4586
|
collapsed_entry = cache.get_model(context.model_id)
|
|
4552
|
-
|
|
4553
|
-
if
|
|
4587
|
+
collapsed_status = extract_thinking_status_from_entry(collapsed_entry)
|
|
4588
|
+
if collapsed_status != "unknown":
|
|
4589
|
+
status = collapsed_status
|
|
4590
|
+
elif context.provider_id is not None:
|
|
4554
4591
|
provider_entry = cache.get_provider_model_entry(
|
|
4555
4592
|
context.model_id,
|
|
4556
4593
|
context.provider_id,
|
|
4557
4594
|
)
|
|
4558
|
-
|
|
4559
|
-
|
|
4560
|
-
|
|
4595
|
+
status = extract_thinking_status_from_entry(provider_entry)
|
|
4596
|
+
else:
|
|
4597
|
+
# No provider hint: aggregate every provider with a
|
|
4598
|
+
# known provider-scoped entry for the model so per-
|
|
4599
|
+
# provider built-in overrides still surface as
|
|
4600
|
+
# ``supported`` rather than collapsing to a misleading
|
|
4601
|
+
# ``unknown``. The router may have just marked every
|
|
4602
|
+
# supporting account as quarantined for this model
|
|
4603
|
+
# while the provider entry (and its built-in override)
|
|
4604
|
+
# is still authoritative for the catalog.
|
|
4605
|
+
# ``get_provider_model_entries`` returns the override-
|
|
4606
|
+
# applied view for every ``(model_id, provider_id)``
|
|
4607
|
+
# row in the cache, including rows whose accounts were
|
|
4608
|
+
# removed from ``_account_support`` by quarantine. The
|
|
4609
|
+
# most permissive status wins because the failure is
|
|
4610
|
+
# attributed to the request, not to any specific
|
|
4611
|
+
# provider.
|
|
4612
|
+
statuses: set[str] = {collapsed_status}
|
|
4613
|
+
for model_id, provider_id in cache.get_provider_model_entries():
|
|
4614
|
+
if model_id != context.model_id:
|
|
4615
|
+
continue
|
|
4616
|
+
entry = cache.get_provider_model_entry(model_id, provider_id)
|
|
4617
|
+
statuses.add(extract_thinking_status_from_entry(entry))
|
|
4618
|
+
if "supported" in statuses:
|
|
4619
|
+
status = "supported"
|
|
4620
|
+
elif "mixed" in statuses:
|
|
4621
|
+
status = "mixed"
|
|
4622
|
+
elif "unsupported" in statuses:
|
|
4623
|
+
status = "unsupported"
|
|
4624
|
+
else:
|
|
4625
|
+
status = collapsed_status
|
|
4561
4626
|
except Exception: # noqa: BLE001
|
|
4562
4627
|
return None
|
|
4563
4628
|
if status in ("unknown", "unsupported"):
|
|
@@ -251,8 +251,17 @@ class ProviderBoundRequest:
|
|
|
251
251
|
is the ownership boundary for path-level transformations such as
|
|
252
252
|
safe compression. Unknown or externally-owned graphs must use
|
|
253
253
|
:meth:`set_provider_payload` instead.
|
|
254
|
+
|
|
255
|
+
When ``increment_generation=True`` the call begins a new generation
|
|
256
|
+
that supersedes any previously serialized/frozen dispatch body.
|
|
257
|
+
The dispatch-freeze flag is reset alongside the cached serialized
|
|
258
|
+
bytes so the next ``serialize_provider_payload`` call re-encodes
|
|
259
|
+
the freshly adopted graph. This is what allows the
|
|
260
|
+
post-selection cross-protocol transcoder to replace the
|
|
261
|
+
preflight-prepared body after a previous attempt has already
|
|
262
|
+
serialized and dispatched once.
|
|
254
263
|
"""
|
|
255
|
-
if self._frozen:
|
|
264
|
+
if self._frozen and not increment_generation:
|
|
256
265
|
raise RuntimeError("provider payload is frozen")
|
|
257
266
|
object.__setattr__(self, "_provider_payload", dict(payload))
|
|
258
267
|
object.__setattr__(self, "mutated", True)
|
|
@@ -261,6 +270,9 @@ class ProviderBoundRequest:
|
|
|
261
270
|
self.diagnostics.generation_changes += 1
|
|
262
271
|
self.mutation_log.append(PayloadMutation(self.payload_generation, reason))
|
|
263
272
|
del self.mutation_log[: -self.mutation_log_limit]
|
|
273
|
+
# A new generation invalidates the previous dispatch freeze;
|
|
274
|
+
# the newly adopted graph is the canonical provider payload.
|
|
275
|
+
object.__setattr__(self, "_frozen", False)
|
|
264
276
|
object.__setattr__(self, "_provider_bytes", None)
|
|
265
277
|
object.__setattr__(self, "_serialized_generation", None)
|
|
266
278
|
|
|
@@ -309,6 +321,15 @@ class ProviderBoundRequest:
|
|
|
309
321
|
incremented so
|
|
310
322
|
downstream caches (segmentation, prepared-transcode) can detect
|
|
311
323
|
staleness.
|
|
324
|
+
|
|
325
|
+
When ``increment_generation=True`` the call begins a brand-new
|
|
326
|
+
generation that supersedes any previously serialized/frozen
|
|
327
|
+
dispatch body. The serialized-bytes cache and the dispatch-freeze
|
|
328
|
+
flag are both reset so the next ``serialize_provider_payload`` call
|
|
329
|
+
re-encodes the new graph; the retry path through
|
|
330
|
+
``_apply_selected_provider_transcode`` relies on this so a
|
|
331
|
+
cross-protocol translation against a different selected provider
|
|
332
|
+
can replace a body that the previous attempt already serialized.
|
|
312
333
|
"""
|
|
313
334
|
if not increment_generation and self._frozen:
|
|
314
335
|
raise RuntimeError("provider payload is frozen")
|
|
@@ -321,6 +342,10 @@ class ProviderBoundRequest:
|
|
|
321
342
|
PayloadMutation(self.payload_generation, "set_provider_payload")
|
|
322
343
|
)
|
|
323
344
|
del self.mutation_log[: -self.mutation_log_limit]
|
|
345
|
+
# A new generation invalidates any prior serialized/frozen
|
|
346
|
+
# dispatch body — the new graph is the canonical provider
|
|
347
|
+
# payload until the next serialization call.
|
|
348
|
+
object.__setattr__(self, "_frozen", False)
|
|
324
349
|
object.__setattr__(self, "_provider_bytes", None)
|
|
325
350
|
object.__setattr__(self, "_serialized_generation", None)
|
|
326
351
|
|
|
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
|
|
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
|