Skip to content

Add experimental API annotations from schema stability markers#875

Open
stephentoub wants to merge 7 commits intomainfrom
experimental-api-annotations
Open

Add experimental API annotations from schema stability markers#875
stephentoub wants to merge 7 commits intomainfrom
experimental-api-annotations

Conversation

@stephentoub
Copy link
Collaborator

Summary

The api.schema.json from the @github/copilot npm package includes a "stability": "experimental" field on certain RPC methods, but none of the code generators were reading or using it. This PR propagates those markers into the generated SDK code across all four languages.

Experimental APIs annotated

RPC Method Group
session.fleet.start Fleet
session.agent.list Agent
session.agent.getCurrent Agent
session.agent.select Agent
session.agent.deselect Agent
session.compaction.compact Compaction

What's annotated

Three levels of annotation are applied:

  1. API classes/groups — when all methods in a group are experimental, the group itself is annotated (e.g., FleetApi, AgentApi, CompactionApi)
  2. Data types — request and result types for experimental methods (e.g., SessionFleetStartResult, SessionFleetStartRequest)
  3. Methods — only when the containing group is not fully experimental (avoids redundancy)

Language-specific annotations

Language Class/Group Data Type Method
C# [Experimental(Diagnostics.Experimental)] [Experimental(Diagnostics.Experimental)] [Experimental(Diagnostics.Experimental)] (only if group is mixed)
TypeScript /** @experimental */ /** @experimental */ /** @experimental */ (only if group is mixed)
Python # Experimental: comment # Experimental: comment docstring warning (only if group is mixed)
Go // Experimental: comment // Experimental: comment // Experimental: comment (only if group is mixed)

C# details

  • A Diagnostics.Experimental internal const ("GHCP001") is generated in Rpc.cs and referenced by all [Experimental] attributes
  • The SDK csproj suppresses GHCP001 internally (the SDK must construct its own experimental types); consumers still see the warning
  • The test csproj also suppresses GHCP001 so tests can exercise experimental APIs

Files changed

Codegen scripts (scripts/codegen/):

  • utils.tsstability?: string on RpcMethod, isNodeFullyExperimental() helper
  • csharp.ts, typescript.ts, python.ts, go.ts — read stability, emit annotations

Generated files: dotnet/src/Generated/Rpc.cs, nodejs/src/generated/rpc.ts, python/copilot/generated/rpc.py, go/rpc/generated_rpc.go

Project files: dotnet/src/GitHub.Copilot.SDK.csproj, dotnet/test/GitHub.Copilot.SDK.Test.csproj (NoWarn for GHCP001)

Read the 'stability' field from api.schema.json and propagate it to
generated code in all four SDK languages. APIs marked as experimental
in the schema (fleet, agent, compaction) now carry appropriate
annotations in the generated output.

Changes to codegen scripts (scripts/codegen/):
- utils.ts: Add stability field to RpcMethod; add isNodeFullyExperimental helper
- csharp.ts: Emit [Experimental(Diagnostics.Experimental)] on types and API classes
- typescript.ts: Emit /** @experimental */ JSDoc on types and groups
- python.ts: Emit # Experimental comments on types and API classes, docstrings on methods
- go.ts: Emit // Experimental: comments on types and API structs

Design decisions:
- When all methods in a group are experimental, the group/class is
  annotated and individual methods are not (annotation is inherited)
- Data types (request/result) for experimental methods are also annotated
- C# uses a Diagnostics.Experimental const ("GHCP001") referenced by all attributes
- SDK csproj suppresses GHCP001 internally; consumers still see warnings

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@stephentoub stephentoub requested a review from a team as a code owner March 17, 2026 15:31
Copilot AI review requested due to automatic review settings March 17, 2026 15:31
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Propagates "stability": "experimental" markers from @github/copilot’s api.schema.json through the repo’s code generators so the generated RPC surfaces across Node/TS, Python, Go, and .NET are annotated as experimental.

Changes:

  • Extend the shared RPC schema model to carry stability and add isNodeFullyExperimental() to detect fully-experimental groups.
  • Update all four language generators to emit experimental annotations at the group/type/method level.
  • Regenerate SDK RPC outputs and add .NET project-level suppression for the emitted experimental diagnostic ID (GHCP001) within the SDK/tests.

Reviewed changes

Copilot reviewed 8 out of 11 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
scripts/codegen/utils.ts Adds stability?: string to RpcMethod and introduces isNodeFullyExperimental() helper.
scripts/codegen/typescript.ts Emits /** @experimental */ on generated TS types and on group/method wrappers where appropriate.
scripts/codegen/python.ts Injects “Experimental” comments onto generated dataclasses and adds group/method warnings in wrappers.
scripts/codegen/go.ts Injects “Experimental” comments for generated Go types and groups/methods in wrappers.
scripts/codegen/csharp.ts Emits [Experimental(Diagnostics.Experimental)] attributes for experimental RPC groups/types/methods and generates Diagnostics.Experimental = "GHCP001".
nodejs/src/generated/rpc.ts Regenerated TS RPC surface with @experimental JSDoc markers.
python/copilot/generated/rpc.py Regenerated Python RPC surface with experimental comments and group markers.
go/rpc/generated_rpc.go Regenerated Go RPC surface with experimental comments (currently not gofmt-clean).
dotnet/src/Generated/Rpc.cs Regenerated C# RPC surface with Experimental attributes and Diagnostics constant.
dotnet/src/GitHub.Copilot.SDK.csproj Suppresses GHCP001 during SDK build so the SDK can reference its own experimental APIs.
dotnet/test/GitHub.Copilot.SDK.Test.csproj Suppresses GHCP001 during test builds so tests can reference experimental APIs.

You can also share your feedback on Copilot code review. Take the survey.

stephentoub and others added 2 commits March 17, 2026 11:44
Address review feedback: quicktype generates comments with trailing
whitespace which fails gofmt checks. Add a post-processing step to
strip trailing whitespace from the quicktype output before writing.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
gofmt requires tab indentation (not spaces) and column-aligns struct
field declarations and composite literal keys. Updated the Go codegen
to emit tabs for all indentation and compute proper padding for field
alignment in wrapper structs and constructors.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actions
Copy link
Contributor

✅ Cross-SDK Consistency Review

I've reviewed this PR for consistency across all four SDK implementations (C#, TypeScript, Python, and Go), and I'm pleased to report that the changes maintain excellent cross-language consistency.

What Was Checked

Experimental API annotations were added for these API groups:

  • Fleet APIs (session.fleet.start)
  • Agent APIs (session.agent.list, getCurrent, select, deselect)
  • Compaction APIs (session.compaction.compact)

Consistency Verification ✅

All four SDKs implement the experimental annotations consistently:

Language API Groups/Classes Data Types Annotation Style
C# FleetApi, AgentApi, CompactionApi All request/result types [Experimental(Diagnostics.Experimental)]
TypeScript fleet, agent, compaction objects All interfaces /** @experimental */
Python FleetApi, AgentApi, CompactionApi All dataclasses # Experimental: comment ✅
Go FleetRpcApi, AgentRpcApi, CompactionRpcApi All structs // Experimental: comment ✅

Key Strengths

  1. Complete coverage: All experimental RPC methods and their associated types are annotated in all four languages
  2. Idiomatic implementations: Each language uses appropriate mechanisms:
    • C# uses the proper [Experimental] attribute with diagnostic ID suppression
    • TypeScript uses JSDoc @experimental tags for tooling integration
    • Python and Go use clear comment-based warnings
  3. Unified codegen approach: The changes are driven by schema-based codegen, ensuring future consistency
  4. Developer experience: The annotations provide appropriate compile-time warnings (C#) or documentation hints (other languages)

No Issues Found

No cross-SDK inconsistencies detected. This PR successfully maintains feature parity across all SDK implementations.


Note: This is an automated consistency review focusing on cross-language API parity.

Generated by SDK Consistency Review Agent for issue #875 ·

gofmt expands single-line 'if err != nil { return nil, err }' into
multi-line blocks. Updated Go codegen to emit the multi-line form
directly, avoiding the gofmt diff.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actions
Copy link
Contributor

✅ Cross-SDK Consistency Review

I've reviewed this PR for consistency across all four SDK implementations (TypeScript, Python, Go, and .NET). The implementation is excellent and maintains strong cross-language consistency. Here's what I verified:

🎯 Consistent Annotation Strategy

All four SDKs correctly implement experimental API annotations with appropriate language-specific conventions:

SDK API Groups Data Types Methods (when group not fully experimental)
C# [Experimental(Diagnostics.Experimental)] [Experimental(Diagnostics.Experimental)] [Experimental(Diagnostics.Experimental)]
TypeScript /** @experimental */ /** @experimental */ /** @experimental */
Python # Experimental: comment # Experimental: comment docstring warning ✓
Go // Experimental: comment // Experimental: comment // Experimental: comment ✓

🔍 Verified Consistency Points

  1. Codegen Logic: All four language generators (csharp.ts, typescript.ts, python.ts, go.ts) correctly:

    • Read the stability field from RpcMethod interface (added to utils.ts)
    • Use the shared isNodeFullyExperimental() helper to detect fully-experimental API groups
    • Apply group-level annotations when all methods are experimental (Fleet, Agent, Compaction)
    • Apply data type annotations for request/result types
    • Include method-level annotations only when the group is mixed (avoiding redundancy)
  2. Generated Code: Verified that all experimental APIs are consistently annotated:

    • Fleet API (session.fleet.start) - ✓ annotated in all 4 SDKs
    • Agent API (list, getCurrent, select, deselect) - ✓ annotated in all 4 SDKs
    • Compaction API (compact) - ✓ annotated in all 4 SDKs
    • Request/Result types - ✓ annotated in all 4 SDKs
  3. C#-Specific Diagnostic Suppression: The .NET SDK correctly:

    • Defines Diagnostics.Experimental = "GHCP001" constant in generated code
    • Suppresses GHCP001 in both GitHub.Copilot.SDK.csproj and GitHub.Copilot.SDK.Test.csproj
    • Allows the SDK and tests to use experimental APIs internally while consumers still receive warnings

💡 Design Quality

The implementation shows excellent engineering:

  • DRY principle: Shared isNodeFullyExperimental() helper prevents code duplication
  • Smart redundancy avoidance: Method-level annotations only appear when needed
  • Language idioms: Each SDK uses its ecosystem's standard practices (C# attributes, JSDoc tags, Python docstrings, Go comments)
  • Forward-compatible: The groupExperimental parameter in method generation is ready for future mixed-stability API groups

🎉 Summary

No consistency issues found. This PR successfully propagates experimental API markers from the schema to all four SDK implementations with consistent semantics and appropriate language-specific syntax. Great work! 🚀

Generated by SDK Consistency Review Agent for issue #875 ·

gofmt expands single-line struct definitions with semicolons into
multi-line format. Updated the Go codegen to emit API struct
definitions in multi-line format directly.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actions
Copy link
Contributor

✅ Cross-SDK Consistency Review: PASSED

I've reviewed this PR for cross-language consistency, and I'm pleased to report that all four SDK implementations maintain excellent feature parity for experimental API annotations.

Consistency Summary

All languages properly implement the three-level annotation strategy:

Language Class/Group Annotation Data Type Annotation Method Annotation
C# [Experimental(Diagnostics.Experimental)] on API classes [Experimental(...)] on types On individual methods when group is mixed
TypeScript /** @experimental */ on API group objects /** @experimental */ on interfaces On individual methods when group is mixed
Python # Experimental: comment on API classes # Experimental: comment on dataclasses Docstring warnings when group is mixed
Go // Experimental: comment on API types // Experimental: comment on structs Comments on individual methods when group is mixed

What I Verified

Codegen scripts - All four language generators (csharp.ts, typescript.ts, python.ts, go.ts) properly read the stability field from the schema and emit language-appropriate annotations

Generated code - All experimental RPC methods (session.fleet.start, session.agent.*, session.compaction.compact) have annotations in all four SDKs

API groups - FleetApi, AgentApi, and CompactionApi classes/groups are consistently marked experimental across all languages

Data types - Request and result types for experimental methods are consistently annotated

Language idioms - Each implementation uses the appropriate mechanism for its ecosystem:

  • C# uses [Experimental] attributes with compiler diagnostic suppression
  • TypeScript uses JSDoc @experimental tags
  • Python uses comment-based warnings
  • Go uses comment-based documentation

C# Diagnostic Handling

The C# implementation includes a particularly nice touch with the internal Diagnostics.Experimental const and project-level warning suppression, ensuring the SDK can construct its own experimental types while still surfacing warnings to consumers.

No consistency issues found. This is an exemplary cross-SDK feature implementation! 🎉

Generated by SDK Consistency Review Agent for issue #875 ·

quicktype emits wide-spaced struct fields for column alignment, but
gofmt doesn't column-align when fields have interleaved comments.
Added post-processing to collapse excessive spacing in quicktype
struct field lines and remove trailing blank lines from quicktype
output.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actions
Copy link
Contributor

✅ Cross-SDK Consistency Review: PASSED

I've reviewed this PR for consistency across all four SDK implementations (TypeScript, Python, Go, and .NET), and I'm pleased to report that the experimental API annotations are consistently implemented across all languages.

✅ What's Consistent

1. API Group Annotations - All three fully-experimental groups are properly annotated:

  • FleetApi / fleet group
  • AgentApi / agent group
  • CompactionApi / compaction group

2. Data Type Annotations - All request/result types for experimental methods are annotated:

  • SessionFleetStartResult / SessionFleetStartParams
  • SessionAgentListResult, SessionAgentGetCurrentResult, SessionAgentSelectResult, SessionAgentDeselectResult
  • SessionCompactionCompactResult

3. Language-Idiomatic Annotations - Each SDK uses appropriate conventions:

  • C#: [Experimental(Diagnostics.Experimental)] with diagnostic ID GHCP001 and project-level NoWarn suppressions
  • TypeScript: /** @experimental */ JSDoc tags
  • Python: # Experimental: comments on classes and docstring warnings on methods
  • Go: // Experimental: comments

4. Code Generation - All 4 codegen scripts (csharp.ts, typescript.ts, python.ts, go.ts) were updated with the shared stability field and isNodeFullyExperimental() helper in utils.ts.

💡 Notes

  • The C#-specific infrastructure (Diagnostics.Experimental constant and NoWarn suppressions) is appropriate for C#'s compile-time warning system and aligns with .NET best practices.
  • The three-tier annotation strategy (group → type → method) correctly avoids redundancy when entire groups are experimental.

Great work maintaining feature parity across all SDKs! 🎉

Generated by SDK Consistency Review Agent for issue #875 ·

Removed manual quicktype column-alignment workaround and regenerated
with Go installed locally so formatGoFile() runs gofmt properly.
This ensures the committed output exactly matches what CI produces.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actions
Copy link
Contributor

✅ Cross-SDK Consistency Review

I've reviewed this PR for consistency across all four SDK implementations (Node.js/TypeScript, Python, Go, and .NET). The changes successfully maintain feature parity and consistent API design.

Summary of Changes

This PR adds experimental API annotations across all SDKs by:

  1. Reading the stability: "experimental" field from the schema
  2. Applying language-appropriate annotations to types, API groups, and methods
  3. Implementing the same three-level annotation strategy everywhere

Consistency Analysis

Consistent Implementation Across All Languages

Aspect TypeScript Python Go C#
Codegen utility isNodeFullyExperimental() added to utils.ts
Data type annotations /** @experimental */ JSDoc # Experimental: comment // Experimental: comment [Experimental(Diagnostics.Experimental)] attribute
API group annotations /** @experimental */ when all methods experimental # Experimental: comment when all methods experimental // Experimental: comment when all methods experimental [Experimental(Diagnostics.Experimental)] when all methods experimental
Method annotations Only when group is mixed (not fully experimental) Only when group is mixed Only when group is mixed Only when group is mixed
APIs annotated Fleet, Agent, Compaction Fleet, Agent, Compaction Fleet, Agent, Compaction Fleet, Agent, Compaction

Language-Specific Implementation Details

C# (most sophisticated):

  • Introduces Diagnostics.Experimental = "GHCP001" constant
  • Uses C# [Experimental] attribute (proper compile-time warning)
  • Suppresses warnings in SDK and test projects via NoWarn so internal code can use experimental APIs
  • Consumers see warnings when using experimental APIs

TypeScript:

  • Uses JSDoc /** @experimental */ comments
  • IDE/tooling support via JSDoc conventions

Python:

  • Uses # Experimental: comments for types/groups
  • Uses docstring warnings for methods: """.. warning:: This API is experimental..."""

Go:

  • Uses standard Go documentation comments: // Experimental:
  • Matches idiomatic Go doc conventions

Redundancy Avoidance Logic

All four languages correctly implement the same "skip method annotation when group is fully experimental" logic:

  • TypeScript: parentExperimental parameter tracks group status
  • Python: groupExperimental parameter tracks group status
  • Go: groupExperimental variable tracks group status
  • C#: groupExperimental variable tracks group status

This prevents redundant annotations (e.g., if AgentApi class is marked experimental, individual methods don't need the same annotation).

Conclusion

No consistency issues found. This PR exemplifies excellent cross-SDK development:

  1. ✅ All four SDKs modified simultaneously
  2. ✅ Same experimental APIs annotated in all languages
  3. ✅ Language-appropriate annotation styles used (attributes, JSDoc, comments)
  4. ✅ Same redundancy avoidance logic implemented everywhere
  5. ✅ Codegen infrastructure properly extended with shared utilities

The implementation respects each language's idioms while maintaining conceptual consistency. Great work! 🎉

Generated by SDK Consistency Review Agent for issue #875 ·

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants