Preserve typed nested unions in SDK codegen - #2486
Conversation
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Go can still expose raw catalogue fields, Rust gains a source-breaking public field, and Java’s update profile can undo the exact schema pin.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review tier: Balanced
Findings: 2
New issues introduced by this change (2)
| Severity | Finding |
|---|---|
go/rpc/catalogue_conformance_test.go — This assertion only exercises the two known candidate variants, which decode into typed structs and… |
|
java/scripts/codegen/package.json — The documented Java schema-update profile does not preserve this exact pin:… |
What changed in this PR
Adds schema-pinned, typed catalog.search bindings across all SDKs, including union generation, raw-card filtering, and conformance tests.
Changes:
- Pins code generation to
@github/copilot@1.0.83-2. - Generates catalogue APIs and nested candidate/result types for six languages.
- Adds cross-language conformance coverage and regenerates newer schema surfaces.
| File | Description |
|---|---|
.github/workflows/update-copilot-dependency.yml |
Updates codegen dependencies exactly. |
dotnet/src/Generated/Rpc.cs |
Generates catalogue and newer RPC types. |
dotnet/src/Generated/SessionEvents.cs |
Regenerates session events. |
dotnet/test/Unit/CatalogueConformanceTests.cs |
Tests catalogue model conformance. |
go/rpc/catalogue_conformance_test.go |
Tests catalogue decoding and leakage. |
go/rpc/zrpc.go |
Generates catalogue and newer RPC APIs. |
go/rpc/zsession_encoding.go |
Encodes added session events. |
go/rpc/zsession_events.go |
Generates session-event models. |
go/zsession_events.go |
Exports added event types. |
java/scripts/codegen/java.ts |
Supports nested discriminated unions. |
java/scripts/codegen/package-lock.json |
Locks the schema package. |
java/scripts/codegen/package.json |
Pins the Java schema dependency. |
java/sdk/src/generated/java/com/github/copilot/generated/AgentModelPolicy.java |
Adds generated model policy. |
java/sdk/src/generated/java/com/github/copilot/generated/AssistantFusionPhaseActivityEvent.java |
Adds Fusion activity event. |
java/sdk/src/generated/java/com/github/copilot/generated/CompletionReceiptEventRange.java |
Adds receipt range type. |
java/sdk/src/generated/java/com/github/copilot/generated/CompletionReceiptFinalTool.java |
Adds receipt tool type. |
java/sdk/src/generated/java/com/github/copilot/generated/CompletionReceiptStopReason.java |
Adds receipt stop reasons. |
java/sdk/src/generated/java/com/github/copilot/generated/CompletionReceiptToolStatus.java |
Adds receipt tool statuses. |
java/sdk/src/generated/java/com/github/copilot/generated/CustomAgentsUpdatedAgent.java |
Regenerates agent event data. |
java/sdk/src/generated/java/com/github/copilot/generated/FusionPhaseActivityKind.java |
Adds Fusion activity kinds. |
java/sdk/src/generated/java/com/github/copilot/generated/FusionPhasePlanStep.java |
Adds Fusion plan steps. |
java/sdk/src/generated/java/com/github/copilot/generated/PermissionRequestedEvent.java |
Regenerates permission events. |
java/sdk/src/generated/java/com/github/copilot/generated/SessionCompletionReceiptEvent.java |
Adds completion receipt event. |
java/sdk/src/generated/java/com/github/copilot/generated/SessionEvent.java |
Registers added event variants. |
java/sdk/src/generated/java/com/github/copilot/generated/SessionFusionResolvedEvent.java |
Regenerates Fusion event data. |
java/sdk/src/generated/java/com/github/copilot/generated/SubagentCompletedEvent.java |
Regenerates completion data. |
java/sdk/src/generated/java/com/github/copilot/generated/SubagentFailedEvent.java |
Regenerates failure data. |
java/sdk/src/generated/java/com/github/copilot/generated/UserMessageEvent.java |
Regenerates message event data. |
java/sdk/src/generated/java/com/github/copilot/generated/rpc/AgentInfo.java |
Adds model policy metadata. |
java/sdk/src/generated/java/com/github/copilot/generated/rpc/AgentModelPolicy.java |
Adds RPC model policy. |
java/sdk/src/generated/java/com/github/copilot/generated/rpc/CatalogAiSkillCandidate.java |
Models AI skill candidates. |
java/sdk/src/generated/java/com/github/copilot/generated/rpc/CatalogAiSkillCandidateProvenance.java |
Models skill provenance. |
java/sdk/src/generated/java/com/github/copilot/generated/rpc/CatalogCandidate.java |
Adds candidate union base. |
java/sdk/src/generated/java/com/github/copilot/generated/rpc/CatalogCandidateSource.java |
Adds source union base. |
java/sdk/src/generated/java/com/github/copilot/generated/rpc/CatalogCandidateSourceEmbedded.java |
Models embedded sources. |
java/sdk/src/generated/java/com/github/copilot/generated/rpc/CatalogCandidateSourceUrl.java |
Models URL sources. |
java/sdk/src/generated/java/com/github/copilot/generated/rpc/CatalogMcpServerCandidate.java |
Models MCP candidates. |
java/sdk/src/generated/java/com/github/copilot/generated/rpc/CatalogMcpServerCandidateProvenance.java |
Models MCP provenance. |
java/sdk/src/generated/java/com/github/copilot/generated/rpc/CatalogMcpServerInstallability.java |
Models installation status. |
java/sdk/src/generated/java/com/github/copilot/generated/rpc/CatalogSearchSucceeded.java |
Models successful searches. |
java/sdk/src/generated/java/com/github/copilot/generated/rpc/DiscoveredHook.java |
Adds hook discovery type. |
java/sdk/src/generated/java/com/github/copilot/generated/rpc/HookOrigin.java |
Adds hook origins. |
java/sdk/src/generated/java/com/github/copilot/generated/rpc/HookType.java |
Regenerates hook types. |
java/sdk/src/generated/java/com/github/copilot/generated/rpc/HooksDiscoverParams.java |
Adds hook discovery input. |
java/sdk/src/generated/java/com/github/copilot/generated/rpc/HooksDiscoverResult.java |
Adds hook discovery output. |
java/sdk/src/generated/java/com/github/copilot/generated/rpc/QueuePendingItems.java |
Adds queued-message identity. |
java/sdk/src/generated/java/com/github/copilot/generated/rpc/SandboxConfigUserPolicyNetwork.java |
Updates network documentation. |
java/sdk/src/generated/java/com/github/copilot/generated/rpc/SandboxConfigUserPolicyNetworkProxy.java |
Updates proxy constraints. |
java/sdk/src/generated/java/com/github/copilot/generated/rpc/ServerHooksApi.java |
Adds hook discovery API. |
java/sdk/src/generated/java/com/github/copilot/generated/rpc/ServerRpc.java |
Exposes generated namespaces. |
java/sdk/src/generated/java/com/github/copilot/generated/rpc/ServerSessionsApi.java |
Adds persisted-event reads. |
java/sdk/src/generated/java/com/github/copilot/generated/rpc/SessionModelSwitchToParams.java |
Updates model-switch semantics. |
java/sdk/src/generated/java/com/github/copilot/generated/rpc/SessionsReadPersistedEventsParams.java |
Adds persisted-event parameters. |
java/sdk/src/generated/java/com/github/copilot/generated/rpc/SessionsReadPersistedEventsResult.java |
Adds persisted-event results. |
java/sdk/src/generated/java/com/github/copilot/generated/rpc/SubagentSettingsEntry.java |
Adds subagent model policy. |
java/sdk/src/test/java/com/github/copilot/RpcSessionStateExtrasE2ETest.java |
Updates session-state fixtures. |
java/sdk/src/test/java/com/github/copilot/generated/CatalogConformanceTest.java |
Tests Java catalogue semantics. |
java/sdk/src/test/java/com/github/copilot/generated/rpc/GeneratedRpcRecordsCoverageTest.java |
Updates generated-record coverage. |
nodejs/src/generated/rpc.ts |
Adds typed catalogue RPC and filtering. |
nodejs/src/generated/session-events.ts |
Regenerates session-event types. |
nodejs/test/catalogue-conformance.test.ts |
Tests TypeScript catalogue behavior. |
nodejs/test/e2e/disabled_mcp_servers.e2e.test.ts |
Updates E2E configuration. |
nodejs/test/e2e/session_config.e2e.test.ts |
Updates E2E configuration. |
python/copilot/generated/rpc.py |
Generates catalogue and newer RPC types. |
python/copilot/generated/session_events.py |
Regenerates session events. |
python/test_rpc_generated.py |
Tests generated catalogue behavior. |
rust/src/generated/api_types.rs |
Generates catalogue and newer API types. |
rust/src/generated/rpc.rs |
Adds typed catalogue RPC access. |
rust/src/generated/session_events.rs |
Regenerates session events. |
rust/tests/catalogue_conformance_test.rs |
Tests Rust catalogue semantics. |
rust/tests/e2e/rpc_session_state_extras.rs |
Updates subagent settings fixture. |
scripts/codegen/catalogue-conformance.ts |
Validates catalogue schema invariants. |
scripts/codegen/package-lock.json |
Locks codegen schema dependencies. |
scripts/codegen/package.json |
Adds schema pin and conformance command. |
scripts/codegen/python.ts |
Normalizes the AI acronym. |
scripts/codegen/typescript.ts |
Generates catalogue response sanitization. |
scripts/codegen/utils.ts |
Uses dedicated codegen dependencies. |
Files not reviewed (5)
- go/rpc/zsession_encoding.go: Generated file
- go/rpc/zsession_events.go: Generated file
- go/zsession_events.go: Generated file
- java/scripts/codegen/package-lock.json: Generated file
- scripts/codegen/package-lock.json: Generated file
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
bc93c27 to
de78eae
Compare
This comment has been minimized.
This comment has been minimized.
b2ac890 to
0cc1b2c
Compare
de78eae to
c0813e4
Compare
|
Thanks for fixing the Java The remaining blocker is broader: we should not solve this by special-casing Please rework the solution around that general mechanism, with conformance coverage across all six SDKs for known nested-union variants and unknown variants. For tracking, I've moved this to draft - please mark as ready to review when appropriate. |
c0813e4 to
784dc1d
Compare
This comment has been minimized.
This comment has been minimized.
|
@SteveSandersonMS Addressed the blocker from your review comment at The generator now has a shared Language mapping is derived from that policy:
A synthetic Both generation-drift checks, all six required SDK checks, CodeQL, and the cross-SDK consistency review are green. There are zero unresolved review threads; the final diff is 46 files against current |
There was a problem hiding this comment.
Thanks for the update. The current revision is still too broad for this PR.
To move forward, please keep this change strictly minimal and schema-driven: ensure the new logic does not modify unrelated RPC codegen output at all.
If you want to continue, please submit that narrowly scoped alternative. Otherwise, please close this PR.
For tracking, I have moved this to draft - please mark as ready to review when appropriate.
784dc1d to
cf2ebef
Compare
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
4aec5d5 to
6f8e817
Compare
This comment has been minimized.
This comment has been minimized.
SDK Consistency Review — PR #2486Scope: This PR extends the codegen pipeline ( Cross-SDK coverage checked:
All six language SDKs received matching generated types, matching runtime rejection semantics (unknown/missing discriminator → error, not silent fallback), and equivalent test coverage for the same scenarios (typed nested variants, opaque handle preservation, secret/ Naming/API parity: Generated type names follow each language's conventions correctly (e.g. Conclusion: No cross-SDK consistency issues identified — this PR maintains full feature parity across Node.js, Python, Go, .NET, Java, and Rust, with each SDK receiving equivalent generated code and dedicated conformance tests.
|
|
@SteveSandersonMS I have applied the narrower interpretation from your changes-requested review at The structural trigger is now deliberately narrow and schema-only: a closed discriminated RPC result whose variant directly owns an array of another closed discriminated union. The policy graph then includes only nested closed unions below those list elements. No generator checks a catalogue method or type name. The exact A neutral synthetic I also compared every real generated artefact against
There are no MCP plan generated types, unrelated RPC hunks, session-event changes, or E2E adaptations. The final PR diff is 33 files, including generator/conformance sources and six-language behavioural tests. Generation drift, Java generation drift, all six required SDK checks, CodeQL, exact package checks, and the independent minimality review pass. Conformance covers known variants, refusal/failure variants, opaque handles, unknown/missing outer and nested discriminators, and extra untrusted fields. I have kept the PR draft and will not mark it ready while your CHANGES_REQUESTED decision remains active. |
|
Sorry but it doesn't look like this is working out. Even just looking at the first file in the PR If I've misunderstood some reason why these changes are 100% safe please let me know but please don't drop a lot more code changes here without first addressing this core point. I'll close to indicate to your bot that we don't want more similar iterations. |
|
@gokhanarkan According to Copilot, the only language where existing RPC codegen didn't handle the nested unions properly was Java. If that sounds right to you, and if you can streamline the PR down to only impact Java (and confirm it's nonbreaking, as in doesn't change the RPC output in a way that affects types other than the experimental Catalog ones), we can definitely take an objective fix like that. Hope that's OK! |
thank you @SteveSandersonMS , this works for me! I will create a separate & focused pr and tag you! tysm! |

Summary
Part of #2106.
Narrow generated scope
For the exact current schema, the structural selector matches only
catalog.searchand derives exactly this policy graph:CatalogSearchResultCatalogCandidateCatalogCandidateSourceGeneration conformance asserts both facts, so any future widening fails for explicit review instead of silently changing generated APIs.
Language mapping remains idiomatic and limited to that graph:
List<Object>/ObjectNo generator source checks
CatalogCandidate,Catalog*, orcatalog.search. A synthetic non-catalogue result proves the same structural selection, TypeScript projection, and Java promotion.Schema input
Exact Copilot CLI
1.0.83-5, resolved from the canonical published release package. Java's npm schema input is exact and both the Maven update profile and dependency workflow use--save-exact.Conformance
Published catalogue result types exercise the selected graph across all six SDKs:
Validation
mvn verify: passedThe final diff is 33 files against current
main. It contains no unrelated generated RPC output, session-event churn, E2E adaptations, downloader, materialisation policy, or planning/apply generated types or business logic.