feat(service-pools): add priority failover and AI routing - #1717
Merged
Merged
Conversation
Support priority tiers with balancing, bounded retries, durable cooldown, and exact member authorization and accounting. Add same-API and AI chat contracts, gateway aliases, and REST, CLI, and dashboard configuration. Closes #1680
📊 Code coverage
Gate: line coverage must stay at or above the threshold. Ratchet plan (W21): Backend → 55%, CLI → 50%, Frontend → 30% by quarter end. |
9 tasks done
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes #1680.
A service pool currently selects one connection before dispatch, so an upstream 429 or transport failure reaches the caller even when another usable connection exists. This adds priority pools that keep one stable route, balance within each priority tier, and try eligible backups under a bounded failover policy. For example, a platform connection can serve first and an authorized BYOK connection can serve after a retryable rejection.
ServicePoolwith member priorities, independent round-robin/weighted tier balancing, bounded attempts and deadlines, replay limits, and durable operation-specific cooldown. Existing round-robin/weighted pools retain single-attempt behavior. Routing has no Oracle dependency.same_apicompatibility andai_chattranslation between supported OpenAI Completions, Responses, and Anthropic Messages providers, with explicit member models and the gateway aliaspool:<slug>. Preserve configured destinations and apply live ownership, scopes, grants, operation policy, approvals, and node capability checks before member execution.nyxid pool. Add per-attempt audit/response attribution, exact member accounting, durable settlement/recovery, and cancellation support for node-routed attempts.Behavior and CLI
The issue's CLI sketch is supported:
nyxid pool create --slug my-llm --name "My LLM" --strategy priority nyxid pool add-member my-llm --service platform-chat --priority 0 nyxid pool add-member my-llm --service my-chat-key --priority 10 nyxid pool set-failover my-llm --retry-on 429,5xx,timeout,node_offline --max-attempts 3 nyxid pool set-strategy my-llm priority --tier-balance weighted nyxid pool health my-llm --method POST --path /chat/completionsMember examples assume existing compatible connections owned by the pool's person or organization. Platform access uses an ordinary same-owner platform-bound
UserServicewith live grants.ai_chatmembers additionally specify a model. Candidate inspection reports unsuitable members and required compatibility declarations or node upgrades.Inline policy flags merge only supplied fields, including nested cooldown settings. JSON files support full configuration and atomic membership/contract changes. Policy updates read one pool ID/revision snapshot and send one PUT; conflicts do not silently retry.
5xxexpands to the supported 500/502/503/504/529 triggers.Ambiguous unsafe-method replay requires explicit
--retry-ambiguous-dispatchopt-in. Configuring 5xx/timeout triggers alone does not enable it. Provider switching stops after the first nonempty client-visible output. Caller cancellation and billing lease loss cancel work without penalizing a healthy upstream. Known usage is settled for each attempted provider; unknown token usage remains unknown. Local authorization, approval, rate-limit, and billing denials are terminal.See the service pool guide for complete configuration and operating behavior, and the routing proof for authorization and routing invariants.
Test Plan
cargo build -p nyxid-clipassed.cargo clippy --workspace --all-targets -- -D warnings,cargo fmt --all --check,git diff --check, andscripts/check-rci-backend-boundary.shpassed on the final implementation snapshot.CI will validate the PR against the current base. The branch merges cleanly with
mainat82dcf3bf; the local verification above was performed on the implementation branch based one96a5078.Rollout and rollback
Upgrade all backend replicas and management clients before creating priority pools. Node-routed priority members require an upgraded, reconnected node advertising
http_cancellation; inspection explains when this is missing. Before downgrading, convert or delete every priority pool, including disabled pools. These requirements and conversion examples are documented in the guide. No Oracle migration is needed.Checklist