Skip to content

Possible naming improvements via codegen changes#1043

Draft
SteveSandersonMS wants to merge 10 commits intomainfrom
stevesa/rpc-naming-improvments
Draft

Possible naming improvements via codegen changes#1043
SteveSandersonMS wants to merge 10 commits intomainfrom
stevesa/rpc-naming-improvments

Conversation

@SteveSandersonMS
Copy link
Copy Markdown
Contributor

@SteveSandersonMS SteveSandersonMS commented Apr 8, 2026

Draft of possible changes to RPC naming convention changes to fix #1035

This PR improves generated public type names across the SDKs by moving naming decisions into the shared schema/codegen pipeline instead of relying on language-specific quirks.

The goal is to make generated names:

  • shorter when the old names were just path concatenation noise
  • more specific when the old names were too generic to be useful
  • more consistent across TypeScript, C#, Go, and Python
  • more stable, because naming now follows a common set of rules plus explicit schema-local overrides where the API really wants a specific public name

Main naming rules

The naming is now mostly mechanical rather than hand-curated:

  1. Derive names from the RPC method / event identity first

    • Example: account.getQuota becomes an AccountQuota root instead of AccountGetQuotaResult.
  2. Drop generic namespace and filler words

    • Strip prefixes like session.
    • Strip terminal filler verbs like get, read, and list when they are only structural
  3. Singularize list entities

    • Example: models.list uses Model for nested item types and ModelList for the top-level result
  4. Keep top-level wrapper words only when they are actually useful

    • Request / Result remain for top-level params/results
    • nested helper types stop inheriting repeated ...Request...Result...Value...Item noise
  5. Drop purely structural wrapper property names in nested helpers

    • Words like data, result, request, response, kind, value, etc. are removed when they are just containers, not meaningful domain terms
  6. Normalize overlapping words

    • Avoid awkward duplication like requested + request
  7. Use explicit schema-local names for true API surface decisions

    • When the API really wants a specific public name, that name is declared in the schema instead of in generator-side override maps

Before / after examples

Previously too long

Before After
AccountGetQuotaResultQuotaSnapshotsValue AccountQuotaSnapshot
SessionPermissionsHandlePendingPermissionRequestResult PermissionRequestResult
SessionToolsHandlePendingToolCallResult HandleToolCallResult
SessionUiElicitationRequestRequestedSchema UiElicitationSchema
SessionUiHandlePendingElicitationRequestResult UiElicitationResponse
SessionUiHandlePendingElicitationResult UiElicitationResult
ToolExecutionCompleteDataResultContentsItemResourceLinkIconsItemTheme ToolExecutionCompleteContentResourceLinkIconTheme
UserMessageDataAttachmentsItemSelectionSelectionEnd UserMessageAttachmentSelectionDetailsEnd

Previously too short / too generic

Before After
Entry SessionFsReaddirWithTypesEntry / SessionFSReaddirWithTypesEntry
End UserMessageAttachmentSelectionDetailsEnd
Mode SessionMode
SessionModeGetResultMode SessionMode

A few especially notable cases

  • The worst "path explosion" example was the old icon theme helper name:

    • ToolExecutionCompleteDataResultContentsItemResourceLinkIconsItemTheme
    • now: ToolExecutionCompleteContentResourceLinkIconTheme
  • The worst "too generic to understand in isolation" examples were names like:

    • Entry
    • End
    • Mode

    Those now carry enough domain context to be understandable in generated SDKs without needing to inspect the surrounding method/property path.

API-specific naming that is now explicit

A few names are intentionally chosen as API surface names rather than just synthesized mechanically, for example:

  • UiElicitationResponse
  • UiElicitationResult
  • HandlePendingElicitationRequest
  • PermissionDecision
  • PermissionDecisionRequest
  • PermissionRequestResult
  • ModeGetResult
  • ModeSetResult
  • HandleToolCallResult

That keeps the generator logic generic while still letting the schema declare clear public names where needed.

TypeScript note

TypeScript still avoids exploding the surface area with every synthesized helper as a named export. Explicit public names are preserved where intended, while synthetic helper naming is mainly used to improve the non-TS SDKs and shared generation consistency.

Co-Authored-By: SteveSandersonMS <1101362+SteveSandersonMS@users.noreply.github.com>
@github-actions

This comment has been minimized.

Copy link
Copy Markdown
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

Generated by SDK Consistency Review Agent for issue #1043

/**
* The elicitation response (accept with form values, decline, or cancel)
*/
export interface UiElicitationResponse {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Duplicate interface declaration

UiElicitationResponse is declared twice in this file (also at line 1073). TypeScript's declaration merging means this compiles, but it's a codegen artifact indicating that the same schema structure appears in two places without a shared $ref. The first occurrence (line 1073) is the result of session.ui.elicitation, and this second occurrence (line 1204) is the type for the result field in HandlePendingElicitationRequest.

In Go and Python, these two occurrences generate separate types (UIElicitationResponse and ResultClass). The duplicate here suggests the two schema locations should share the same definition reference, which would also fix the ResultClass naming in Go and Python.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed in add04df. TypeScript now deduplicates repeated exported declarations emitted by per-method json-schema-to-typescript compiles, so this no longer produces a second UiElicitationResponse declaration.

… side

Co-Authored-By: SteveSandersonMS <1101362+SteveSandersonMS@users.noreply.github.com>
@github-actions

This comment has been minimized.

Copy link
Copy Markdown
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

Generated by SDK Consistency Review Agent for issue #1043

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

Addressed the review findings in add04df. Specifically: (1) TS now deduplicates repeated named export blocks from per-method json-schema-to-typescript compiles, which removes the duplicate SessionMode and duplicate UiElicitationResponse declarations; and (2) the Go/Python quicktype-based generators now collapse placeholder *Class duplicates onto the explicit titled type when the structures are identical, so HandlePendingElicitationRequest.result now uses UIElicitationResponse instead of ResultClass.

@github-actions

This comment has been minimized.

Copy link
Copy Markdown
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

Generated by SDK Consistency Review Agent for issue #1043



class HostType(Enum):
class ContextChangedHostType(Enum):
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Naming inconsistency: This enum is named ContextChangedHostType here but StartContextHostType in Go and .NET. Consider adding a title/titleSuggestion to this schema node so quicktype produces StartContextHostType to match.



class Operation(Enum):
class ChangedOperation(Enum):
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Naming inconsistency: Python collapses both the plan.changed and workspace.fileChanged operation enums into a single ChangedOperation, while Go and .NET produce two separate enums PlanChangedOperation and WorkspaceFileChangedOperation. If they should be distinct, schema-level title/titleSuggestion overrides on each individual enum schema would resolve this.



class PermissionRequestKind(Enum):
class Kind(Enum):
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Naming inconsistency: Kind is too generic and lacks context. Go names this PermissionRequestKind (renamed from PermissionRequestedDataPermissionRequestKind in this PR). Adding a titleSuggestion: "PermissionRequestKind" to this schema node would align the Python output with Go.

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

This comment has been minimized.

Copy link
Copy Markdown
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

Generated by SDK Consistency Review Agent for issue #1043

ExtensionsLoadedExtensionStatusStarting ExtensionsLoadedExtensionStatus = "starting"
)

// Type aliases for convenience.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Go compilation break: TYPE_ALIASES and CONST_ALIASES reference old type names

The convenience type/const aliases below this line still reference the old generated type names that no longer exist in this file after the renames. For example:

// TYPE_ALIASES in scripts/codegen/go.ts — still points to OLD names:
PermissionRequest        = PermissionRequestedDataPermissionRequest        // ❌ undefined; PermissionRequest is now a struct directly
PermissionRequestKind    = PermissionRequestedDataPermissionRequestKind    // ❌ redeclared (PermissionRequestKind is now a string type at line ~2227)
PermissionRequestCommand = PermissionRequestedDataPermissionRequestCommandsItem  // ❌ undefined
PossibleURL              = PermissionRequestedDataPermissionRequestPossibleUrlsItem // ❌ undefined
Attachment               = UserMessageDataAttachmentsItem                  // ❌ undefined
AttachmentType           = UserMessageDataAttachmentsItemType              // ❌ undefined

And the CONST_ALIASES block similarly references UserMessageDataAttachmentsItemTypeFile, PermissionRequestedDataPermissionRequestKindShell, etc. — all of which have been renamed.

The TYPE_ALIASES and CONST_ALIASES maps in scripts/codegen/go.ts (around line 800) were not updated as part of this PR. They need to be updated to reflect the new generated names, e.g.:

// Suggested fixes:
PossibleURL      = PermissionRequestShellPossibleUrl
Attachment       = UserMessageAttachment
AttachmentType   = UserMessageAttachmentType

// Const aliases:
AttachmentTypeFile = UserMessageAttachmentTypeFile
// etc.

Types like PermissionRequest and PermissionRequestKind are now direct struct/type declarations, so their alias entries can simply be removed (or the alias should map to the new canonical name if needed for backward compat).

type SessionPermissionsHandlePendingPermissionRequestParams struct {
RequestID string `json:"requestId"`
Result SessionPermissionsHandlePendingPermissionRequestParamsResult `json:"result"`
type PermissionDecisionRequest struct {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Go compilation break: non-generated SDK code references old type names

This PR renames SessionPermissionsHandlePendingPermissionRequestParamsPermissionDecisionRequest (and similarly for other types), but the non-generated Go SDK code in go/session.go and go/types.go still references the old names. A full list of ~43 identifiers from the rpc package that are missing includes:

Old name (used in non-generated code) New name (in this PR)
rpc.SessionCommandsHandlePendingCommandParams rpc.CommandsHandlePendingCommandRequest
rpc.SessionUIHandlePendingElicitationParams rpc.HandlePendingElicitationRequest
rpc.SessionUIHandlePendingElicitationParamsResult rpc.UIElicitationResponse
rpc.SessionPermissionsHandlePendingPermissionRequestParams rpc.PermissionDecisionRequest
rpc.ActionAccept / rpc.ActionCancel rpc.UIElicitationActionAccept / rpc.UIElicitationActionCancel
rpc.PropertyTypeBoolean / rpc.PropertyTypeString rpc.UIElicitationSchemaPropertyNumberTypeBoolean / ...String
rpc.SessionUIElicitationParams (structure changed)
rpc.ConventionsPosix / rpc.ConventionsWindows rpc.SessionFSSetProviderConventionsPosix / ...Windows
rpc.EntryTypeDirectory / rpc.EntryTypeFile rpc.SessionFSReaddirWithTypesEntryTypeDirectory / ...File
rpc.ModeInteractive / rpc.ModePlan rpc.SessionModeInteractive / rpc.SessionModePlan
rpc.LevelError etc. rpc.LogLevelError etc.
All rpc.SessionFS*Params rpc.SessionFS*Request

go/session.go, go/types.go, and other non-generated files will need to be updated to use the new names. This is expected to be a significant follow-up change to make the Go SDK compile.

SteveSandersonMS and others added 2 commits April 9, 2026 19:03
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-Authored-By: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 9, 2026

✅ Cross-SDK Consistency Review

All four SDK implementations (Node.js/TypeScript, Python, Go, .NET) are updated in this PR, and the changes are well-coordinated.

What was checked:

  • All renamed generated types (ModelList, UserMessageAttachment, UiElicitationSchema, SessionLogLevel, SessionFSSetProviderConventions, etc.) are consistently applied across all four SDKs
  • The new mcp.discover RPC method is added to all four SDKs with equivalent types (McpDiscoverResult/MCPDiscoverResult, DiscoveredMcpServer/DiscoveredMCPServer, DiscoveredMcpServerSource/DiscoveredMCPServerSource)
  • Non-generated SDK files (session.go, Session.cs, types.ts, client.py, etc.) are all updated to use the new type names

Language conventions are properly respected:

  • TypeScript/C#: Mcp (PascalCase), UiElicitation
  • Go/Python: MCP (initialism), UIElicitation

One Python-only change in client.py: Better type annotations in _extract_transform_callbacks (accepting SystemMessageConfig | dict[str, Any] | None) and cast() calls in list_models(). These are Python-specific type safety improvements (no behavioral change) and don't need equivalents in other SDKs.

No cross-SDK consistency issues found. 🎉

Generated by SDK Consistency Review Agent for issue #1043 ·

SteveSandersonMS and others added 4 commits April 9, 2026 19:38
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
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.

Review all codegenerated type names; provide better names in many cases

1 participant