Add experimental multi-provider BYOK registry config across all six SDKs#1718
Add experimental multi-provider BYOK registry config across all six SDKs#1718stephentoub wants to merge 2 commits into
Conversation
Surfaces the new named-provider / provider-model registry from copilot-agent-runtime#9864 (providers + models on session create/resume) in the .NET, Node, Python, Go, Rust, and Java SDKs. The whole feature is marked experimental in each language using that SDK's existing convention. Custom agents can now bind to provider-qualified BYOK model ids (e.g. "alpha/sonnet"), letting multiple providers, multiple models per provider, and agents/subagents coexist in one session and route inference to the right provider with the configured wire model and headers. Also adds end-to-end coverage for the surface in every SDK (shared replay snapshots under test/snapshots/multi_provider_registry), and exposes "model" on the Java hand-written rpc.AgentInfo so it matches the agent-info type in the other five SDKs. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This PR adds an experimental multi-provider BYOK registry surface (providers + models) to each SDK’s session create/resume configuration, enabling apps to register multiple named providers, define multiple models per provider, and bind custom agents to provider-qualified model IDs (e.g. alpha/sonnet). It also adds Java parity for AgentInfo.model and introduces cross-SDK E2E coverage using shared replay snapshots.
Changes:
- Added new provider/model registry config types and plumbed
providers/modelsthrough session create + resume wire payloads across Rust, Go, Python, Node, Java, and .NET. - Added/updated E2E tests in each language plus shared replay fixtures under
test/snapshots/multi_provider_registry/. - Extended Java
AgentInfowith amodelfield and updated tests accordingly.
Show a summary per file
| File | Description |
|---|---|
| test/snapshots/multi_provider_registry/should_route_delta_turbo_turn_to_its_provider_and_wire_model.yaml | Adds replay fixture for routing the delta/turbo selection to its wire model. |
| test/snapshots/multi_provider_registry/should_route_alpha_sonnet_turn_to_its_provider_and_wire_model.yaml | Adds replay fixture for routing the alpha/sonnet selection to its wire model. |
| test/snapshots/multi_provider_registry/should_route_alpha_haiku_turn_to_its_provider_and_wire_model.yaml | Adds replay fixture for routing the alpha/haiku selection to its wire model. |
| test/snapshots/multi_provider_registry/should_register_multiple_providers_with_custom_agents_bound_to_their_models.yaml | Adds replay fixture used by the registry + agent-binding test case. |
| rust/tests/e2e/multi_provider_registry.rs | Adds Rust E2E coverage for registry creation, agent bindings, and per-provider routing assertions. |
| rust/tests/e2e.rs | Registers the new Rust E2E module. |
| rust/src/wire.rs | Extends Rust wire DTOs for session create/resume with providers and models. |
| rust/src/types.rs | Introduces NamedProviderConfig + ProviderModelConfig and wires them into SessionConfig / ResumeSessionConfig plus serialization tests. |
| python/e2e/test_multi_provider_registry_e2e.py | Adds Python E2E coverage for registry creation, agent bindings, and per-provider routing assertions. |
| python/copilot/session.py | Adds Python TypedDict definitions for NamedProviderConfig and ProviderModelConfig. |
| python/copilot/client.py | Plumbs providers and models through create_session / resume_session and adds snake_case→wire conversion helpers. |
| python/copilot/init.py | Exports NamedProviderConfig and ProviderModelConfig from the public Python package surface. |
| nodejs/test/e2e/multi_provider_registry.e2e.test.ts | Adds Node E2E coverage for registry creation, agent bindings, and per-provider routing assertions. |
| nodejs/src/types.ts | Adds NamedProviderConfig + ProviderModelConfig and exposes them on SessionConfigBase. |
| nodejs/src/index.ts | Re-exports the new Node types from the SDK entry point. |
| nodejs/src/client.ts | Includes providers and models in Node session create/resume RPC payloads. |
| java/src/test/java/com/github/copilot/MultiProviderRegistryE2ETest.java | Adds Java E2E coverage for registry creation, agent bindings, and per-provider routing assertions. |
| java/src/test/java/com/github/copilot/MultiProviderConfigTest.java | Adds Java unit tests for JSON serialization and cloning behavior of the new config types + SessionConfig/ResumeSessionConfig integration. |
| java/src/test/java/com/github/copilot/AgentInfoTest.java | Extends Java tests for the new AgentInfo.model field. |
| java/src/main/java/com/github/copilot/SessionRequestBuilder.java | Plumbs providers and models from config objects into create/resume request DTOs. |
| java/src/main/java/com/github/copilot/rpc/SessionConfig.java | Adds experimental providers/models fields + getters/setters + cloning support. |
| java/src/main/java/com/github/copilot/rpc/ResumeSessionRequest.java | Adds experimental providers/models fields to the internal resume request DTO. |
| java/src/main/java/com/github/copilot/rpc/ResumeSessionConfig.java | Adds experimental providers/models fields + getters/setters + cloning support. |
| java/src/main/java/com/github/copilot/rpc/ProviderModelConfig.java | Introduces Java ProviderModelConfig (experimental) with fluent setters and JSON mapping. |
| java/src/main/java/com/github/copilot/rpc/NamedProviderConfig.java | Introduces Java NamedProviderConfig (experimental) with fluent setters and JSON mapping. |
| java/src/main/java/com/github/copilot/rpc/CreateSessionRequest.java | Adds experimental providers/models fields to the internal create request DTO. |
| java/src/main/java/com/github/copilot/rpc/AgentInfo.java | Adds model to Java AgentInfo for parity with other SDKs. |
| go/types.go | Adds Go NamedProviderConfig + ProviderModelConfig plus SessionConfig/ResumeSessionConfig fields and request struct plumbing. |
| go/internal/e2e/multi_provider_registry_e2e_test.go | Adds Go E2E coverage for registry creation, agent bindings, and per-provider routing assertions. |
| go/client.go | Plumbs Providers and Models into Go create/resume session RPC requests. |
| dotnet/test/E2E/MultiProviderRegistryE2ETests.cs | Adds .NET E2E coverage for registry creation, agent bindings, and per-provider routing assertions. |
| dotnet/src/Types.cs | Adds .NET NamedProviderConfig + ProviderModelConfig and exposes them on SessionConfigBase. |
| dotnet/src/Client.cs | Plumbs Providers/Models into .NET create/resume session requests and registers types for JSON source-gen. |
Copilot's findings
- Files reviewed: 33/33 changed files
- Comments generated: 0
This comment has been minimized.
This comment has been minimized.
Apply prettier (Node) and ruff format (Python) to the new multi-provider registry E2E test files so the format-check CI steps pass. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Cross-SDK Consistency Review ✅This PR adds the multi-provider BYOK registry config ( ✅
|
| Field (wire) | TypeScript | Python | Go | .NET | Java | Rust |
|---|---|---|---|---|---|---|
name |
name |
name |
Name |
Name |
name |
name |
type |
type |
type |
Type |
Type |
type |
provider_type (reserved kw → #[serde(rename="type")]) |
wireApi |
wireApi |
wire_api |
WireAPI |
WireApi |
wireApi |
wire_api |
baseUrl |
baseUrl |
base_url |
BaseURL |
BaseUrl |
baseUrl |
base_url |
apiKey |
apiKey |
api_key |
APIKey |
ApiKey |
apiKey |
api_key |
bearerToken |
bearerToken |
bearer_token |
BearerToken |
BearerToken |
bearerToken |
bearer_token |
azure |
azure |
azure |
Azure |
Azure |
azure |
azure |
headers |
headers |
headers |
Headers |
Headers |
headers |
headers |
✅ ProviderModelConfig — fully consistent
All nine fields (id, provider, wireModel, modelId, name, maxPromptTokens, maxContextWindowTokens, maxOutputTokens, capabilities) are present in every SDK with correct language-idiomatic naming.
✅ providers / models on SessionConfig and ResumeSessionConfig — fully consistent
All SDKs wire both fields for both create and resume paths.
✅ Experimental markers — language-idiomatic and consistently applied
| SDK | Convention used |
|---|---|
| .NET | [Experimental(Diagnostics.Experimental)] on type and members |
| Node.js | @experimental JSDoc tag |
| Go | // Experimental: ... doc comments on fields and types |
| Rust | **Experimental.** leading paragraph in doc comments |
| Python | **Experimental.** in docstrings |
| Java | @CopilotExperimental annotation on class and methods |
✅ AgentInfo.model parity fix
Java's hand-written AgentInfo was the only SDK that lacked the model field. The other five SDKs expose it through their generated types (e.g., AgentInfo.model in Go's rpc.go, Model in .NET's Rpc.cs, model in Node.js's rpc.ts, Rust's generated/api_types.rs). Adding it to Java correctly closes the parity gap without any protocol change.
✅ Rust builder pattern
NamedProviderConfig::new(name, base_url) and ProviderModelConfig::new(id, provider) are Rust-idiomatic; no equivalent is needed in other SDKs, which use object/struct literals or fluent setters.
Summary
No cross-SDK inconsistencies found. The feature is implemented in all six languages with consistent wire semantics, correct language idioms, and appropriate experimental markers.
Generated by SDK Consistency Review Agent for issue #1718 · sonnet46 3.9M · ◷
Why
The CLI protocol recently gained a named-provider / provider-model registry (copilot-agent-runtime#9864):
providersandmodelson session create/resume. This lets an app register several BYOK providers, declare multiple models per provider, and bind custom agents to provider-qualified model ids. None of the SDKs surfaced it yet, so SDK consumers couldn't use multi-provider configurations. This PR closes that gap in all six SDKs (.NET, Node, Python, Go, Rust, Java).What
NamedProviderConfig(name, type, wireApi, baseUrl, apiKey/bearerToken, headers, azure) andProviderModelConfig(id, provider, wireModel, token limits, capabilities), wired onto the session config used for create and resume. Custom agents can reference provider-qualified model ids (e.g.alpha/sonnet).[Experimental]/@CopilotExperimental/Experimental:doc markers / etc.). The whole feature should be treated as experimental for now.AgentInfoparity: addedmodelto the hand-writtencom.github.copilot.rpc.AgentInfoso it matches the agent-info type already exposed by the other five SDKs (the field deserializes from the existingsession.agent.listpayload, so no protocol change).X-Providerheader, and credential.Notes for reviewers
test/snapshots/multi_provider_registry/. There are no per-language snapshots.openai/completionsproviders pointed at the replay proxy (only/chat/completionsis captured); providers are distinguished on the wire by a per-providerX-Providerheader. The agent-binding test additionally includes ananthropicprovider purely to prove heterogeneous providers coexist (no dispatch).AgentInfoTestwas extended for the newmodelfield (7/7).Test plan
dotnet testE2EMultiProviderRegistryE2ETests- 4/4npm run test -- multi_provider_registry- 4/4pytest e2e/test_multi_provider_registry_e2e.py- 4/4go test -run TestMultiProviderRegistryE2E ./internal/e2e- 4/4cargo test --test e2e multi_provider_registry- 4/4mvn test -Dtest=MultiProviderRegistryE2ETest- 4/4, plusAgentInfoTest7/7; spotless clean