feat(providers): dedicated BYOK-vendor providers make hermes/openclaw vendor menus routable (cp#529) #2262
Reference in New Issue
Block a user
Delete Branch "feat/cp529-byok-vendor-providers"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
What
The 20 ids cp#529's routability-aware drift checker flagged as residual drift are CUSTOMER BYOK vendor models for the SHARED upstream vendors (anthropic, openai, gemini, minimax, groq). They were left unroutable because wiring them through the platform-shared
platformprovider would bill the platform's key (a money bug).This PR makes them routable WITHOUT trimming them, by adding 5 dedicated NON-PLATFORM BYOK-vendor providers and wiring them as name-only prefix-routing arms (zero models → no change to the platform menu /
ModelsForRuntime):byok-anthropic^anthropic/byok-openai^openai[:/]byok-gemini^gemini/byok-minimax(?i)^(minimax[:/]|codex-minimax-)groq^groq:Wired in:
byok-anthropic, byok-gemini, byok-openai, byok-minimax→ resolvesanthropic/*,gemini/*,openai/*,minimax/*(12 ids)byok-openai, byok-minimax, groq→ resolvesopenai:*,minimax:*,groq:*(7 ids). The openclaw runtime DEFAULTminimax:MiniMax-M2.7now resolves.byok-minimax→ resolves the BYOK token-plan idcodex-minimax-m2.7(the template'sminimax-token-planroute — same upstream api.minimax.io, tenantMINIMAX_API_KEY) via a narrowly-anchored^codex-minimax-leg, not a broad matcher.Billing-safe
Every new provider has
name != "platform"→IsPlatform() == false→ BYOK billing. The workspace env supplies the tenant's vendor key; the platform key is never used. Verified in the DeriveProvider harness output below (IsPlatform=falsefor all).Collision-free (DeriveProvider verification)
Every matcher is namespaced (slash/colon form), disjoint from the platform vendors' BARE matchers (
anthropic-api ^claude,openai-subscription ^gpt-,openai-api ^openai-api[:/],minimax (?i)^minimax-m,google ^gemini-,minimax-cn ^minimax-cn[:/]). A throwawayLoadManifest()+DeriveProvider(runtime, id, nil)harness resolved all 20 ids +codex-minimax-m2.7to EXACTLY ONE provider, no overlap, no error, none platform:Drift = 0
go run ./cmd/check-template-models:(google-adk is a transient template-fetch 404, unchanged from before this PR, and the checker deliberately does not block on it. It is outside the 20 ids.) The gate is ready to go enforcing.
Tests / codegen
internal/providers+gen+cmd/check-template-models: PASS (runtimes_test.gonative-set expectations updated for the new arms).internal/handlers: PASS.go test -tags serving_e2e -run TestEveryOfferedProviderHasAnArm ./internal/servinge2e/...: PASS (name-only BYOK arms are exempt from platform serving coverage, cp#529).registry_gen.goregenerated viago generate ./cmd/gen-providers/.Byte-sync — the two PRs MUST land together
providers.yamlis byte-identical across both repos (diff -uempty). This PR is paired with molecule-core / molecule-controlplanefeat/cp529-byok-vendor-providers. molecule-core's copy also bumpscanonicalProvidersYAMLSHA256to the new canonical sha (846ddef1…), gated by thesync-providers-yamldrift check. Merging one without the other will turn that gate red.🤖 Generated with Claude Code
cp#529 BYOK-vendor providers. Independently verified DeriveProvider: 20 ids -> byok-* (non-platform/BYOK), platform models unchanged, namespaced matchers disjoint from platform bare-form matchers (no collision), codex-minimax narrow-anchored, drift=0, byte-synced. Approve.
cp#529 BYOK-vendor providers. Independently verified DeriveProvider: 20 ids -> byok-* (non-platform/BYOK), platform models unchanged, namespaced matchers disjoint from platform bare-form matchers (no collision), codex-minimax narrow-anchored, drift=0, byte-synced. Approve.