Skip to content

[Node] Add onElicitationRequest Callback for Elicitation Provider Support#908

Merged
MRayermannMSFT merged 6 commits intomainfrom
mrayermannmsft/elicitation-provider
Mar 30, 2026
Merged

[Node] Add onElicitationRequest Callback for Elicitation Provider Support#908
MRayermannMSFT merged 6 commits intomainfrom
mrayermannmsft/elicitation-provider

Conversation

@MRayermannMSFT
Copy link
Copy Markdown
Contributor

@MRayermannMSFT MRayermannMSFT commented Mar 24, 2026

What

Adds onElicitationRequest to the Node.js SDK's SessionConfig, enabling SDK clients to act as elicitation providers. When a client registers this callback, the SDK negotiates the requestElicitation capability during session create/resume, listens for elicitation.requested broadcast events, invokes the handler, and responds via the handlePendingElicitation RPC. The SDK also automatically updates session.capabilities when capabilities.changed events arrive as providers join or leave. Includes unit tests, E2E tests covering capability reporting, multi-client propagation, and provider disconnect, plus updated README documentation.

Why

The CLI runtime now supports fan-out elicitation — broadcasting structured input requests to all connected clients that advertise elicitation support, with the first response winning. Without this SDK-side change, Node.js clients had no way to register as elicitation providers, limiting these requests to the CLI's own TUI.

@github-actions
Copy link
Copy Markdown
Contributor

Cross-SDK Consistency Review

This PR adds onElicitationRequest callback support to the Node.js/TypeScript SDK, enabling clients to act as elicitation providers. While this is a valuable feature addition, it creates a feature parity gap across the SDK implementations.

Summary of Changes (Node.js Only)

The PR adds:

  1. onElicitationRequest handler in SessionConfig and ResumeSessionConfig
  2. ElicitationHandler and ElicitationRequest types
  3. requestElicitation flag sent during session create/resume
  4. RPC handler registration for elicitation.request callbacks
  5. Automatic capabilities.changed event handling to update session.capabilities dynamically
  6. Comprehensive documentation in README with examples
  7. E2E tests covering single-client and multi-client scenarios

Feature Parity Status

SDK OnUserInputRequest OnElicitationRequest capabilities.changed handling
Node.js ✅ Supported Added in this PR Added in this PR
Python ✅ Supported ❌ Missing ❌ Missing
Go ✅ Supported ❌ Missing ❌ Missing
.NET ✅ Supported ❌ Missing ❌ Missing

Recommendation

The Python, Go, and .NET SDKs should receive equivalent implementations to maintain feature parity. Based on the Node.js changes, each SDK would need:

Python (python/copilot/)

  • Add on_elicitation_request: ElicitationHandler to SessionConfig and ResumeSessionConfig (similar to on_user_input_request)
  • Define ElicitationHandler type alias following the existing UserInputHandler pattern
  • Add request_elicitation flag to create/resume RPC calls
  • Register RPC handler for elicitation.request in client.py
  • Implement _register_elicitation_handler() method in CopilotSession
  • Handle capabilities.changed events to update session.capabilities dynamically
  • Add README documentation and E2E tests

Go (go/)

  • Add OnElicitationRequest ElicitationHandler to SessionConfig and ResumeSessionConfig
  • Define ElicitationHandler func(request ElicitationRequest, invocation ElicitationInvocation) (ElicitationResponse, error)
  • Add RequestElicitation bool to create/resume RPC params
  • Register RPC method handler for elicitation.request in client.go
  • Implement registerElicitationHandler() and handleElicitationRequest() in session.go
  • Handle capabilities.changed events in session event processing
  • Add README documentation and E2E tests

.NET (dotnet/src/)

  • Add OnElicitationRequest property to SessionConfig and ResumeSessionConfig
  • Define ElicitationHandler delegate following the UserInputHandler pattern
  • Add RequestElicitation to create/resume RPC parameters
  • Register RPC handler for elicitation.request in Client.cs
  • Implement RegisterElicitationHandler() and handle callbacks in Session.cs
  • Handle capabilities.changed events to update session capabilities
  • Add README documentation and E2E tests

Note on Blocking

This should not block the Node.js PR from merging, but I recommend:

  1. Creating follow-up issues/PRs to track implementation in other SDKs
  2. Documenting this as a Node.js-only feature temporarily in the main README
  3. Prioritizing Python/Go/.NET implementations to minimize the feature gap duration

The implementation pattern is consistent and well-tested in Node.js, making it straightforward to port to the other SDKs following their respective language idioms.

Generated by SDK Consistency Review Agent for issue #908 ·

@MRayermannMSFT MRayermannMSFT force-pushed the mrayermannmsft/elicitation-provider branch from 3a1ec67 to 75c9be1 Compare March 30, 2026 17:58
@github-actions
Copy link
Copy Markdown
Contributor

Cross-SDK Consistency Review

This PR adds onElicitationRequest callback support to the Node.js SDK only, enabling clients to act as elicitation providers. This creates a feature parity gap with the other SDK implementations.

Current State

✅ Node.js SDK (this PR):

  • Adds SessionConfig.onElicitationRequest?: ElicitationHandler
  • Negotiates requestElicitation capability during session create/resume
  • Listens for elicitation.requested broadcast events
  • Responds via handlePendingElicitation RPC
  • Updates session.capabilities on capabilities.changed events

❌ Python SDK: No elicitation provider support

  • create_session() has no on_elicitation_request parameter
  • Cannot register as elicitation provider

❌ Go SDK: No elicitation provider support

  • SessionConfig struct has no OnElicitationRequest field
  • Cannot register as elicitation provider

❌ .NET SDK: No elicitation provider support

  • SessionConfig class has no OnElicitationRequest property
  • Cannot register as elicitation provider

Recommendation

To maintain feature parity across SDKs, consider adding equivalent elicitation provider APIs to Python, Go, and .NET:

Python:

async def create_session(
    *,
    on_elicitation_request: ElicitationHandler | None = None,
    # ... other params
) -> CopilotSession:

Go:

type SessionConfig struct {
    // ...
    OnElicitationRequest ElicitationHandler
}

.NET:

public class SessionConfig
{
    public ElicitationRequestHandler? OnElicitationRequest { get; set; }
}

All SDKs already support consuming elicitation as a client (via session.ui.elicitation()), but only Node.js can now provide elicitation responses. This asymmetry may confuse users working across multiple language platforms.


Note: If this feature is being rolled out incrementally, consider tracking the cross-language implementation in an issue to ensure consistency is achieved in future PRs.

Generated by SDK Consistency Review Agent for issue #908 ·

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 #908

@github-actions
Copy link
Copy Markdown
Contributor

Cross-SDK Consistency Review

I've reviewed PR #908 for consistency across the four SDK implementations (Node.js/TypeScript, Python, Go, and .NET).

Summary

This PR adds elicitation provider support to the Node.js SDK, enabling clients to handle elicitation.requested broadcast events and act as form-based UI providers. The implementation follows a similar pattern to the existing onUserInputRequest handler and includes:

  • New onElicitationRequest?: ElicitationHandler callback in SessionConfig
  • Automatic requestElicitation: true capability negotiation during session create/resume
  • Event routing for elicitation.requested broadcasts
  • Response handling via session.ui.handlePendingElicitation RPC
  • Tests and documentation

Feature Parity Gaps

This PR widens an existing feature gap. The Node.js SDK has several features that are not available in Python, Go, or .NET:

1. UI Elicitation (Consumer Side) ❌ Python, Go, .NET

The Node.js SDK has had session.ui.elicitation(), session.ui.confirm(), session.ui.select(), and session.ui.input() methods that allow the SDK to request elicitation dialogs from the TUI. These are documented in the Node.js README under "UI Elicitation" but have no equivalent in other SDKs.

2. Commands Support ❌ Python, Go, .NET

The Node.js SDK supports registering slash commands via SessionConfig.commands[], allowing users to invoke custom actions via /commandName in the TUI. The SDK handles command.execute broadcast events and responds via session.commands.handlePendingCommand. This feature doesn't exist in other SDKs.

3. Elicitation Provider Support (This PR) ❌ Python, Go, .NET

This PR adds the ability for Node.js clients to handle elicitation requests, not just call them. None of the other SDKs have this new capability.

Recommendation

While this Node.js-specific feature is well-implemented and valuable, I recommend tracking these cross-SDK consistency issues:

  1. Short term: Document which features are Node.js-only so users choosing between SDKs understand the trade-offs
  2. Medium term: Consider prioritizing feature parity for:
    • UI Elicitation consumer APIs (all SDKs should be able to call elicitation(), confirm(), etc.)
    • Commands support (useful for multi-language CLI tool builders)
  3. Long term: If the elicitation provider pattern proves valuable, port it to other SDKs

The Node.js SDK is becoming the "reference implementation" with significantly more capabilities than the others. This is sustainable if intentional, but may surprise users expecting feature parity across languages.


No blocking issues with this PR — it maintains consistency with Node.js's existing patterns and doesn't introduce inconsistencies within the Node.js SDK itself. The cross-SDK gap is pre-existing and growing.

Generated by SDK Consistency Review Agent for issue #908 ·

@MRayermannMSFT MRayermannMSFT marked this pull request as ready for review March 30, 2026 18:53
@MRayermannMSFT MRayermannMSFT requested a review from a team as a code owner March 30, 2026 18:53
Copilot AI review requested due to automatic review settings March 30, 2026 18:53
Copy link
Copy Markdown
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

Adds elicitation provider support to the Node.js SDK by introducing an onElicitationRequest callback in SessionConfig, allowing SDK clients to receive and answer fan-out elicitation requests and track dynamic capability changes during a session.

Changes:

  • Add onElicitationRequest types/exports and wire capability negotiation (requestElicitation) into session create/resume.
  • Handle elicitation.requested broadcast events and apply capabilities.changed updates to session.capabilities.
  • Add unit + E2E coverage and update docs; bump @github/copilot dependency versions used by Node + test harness.

Reviewed changes

Copilot reviewed 9 out of 11 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
test/harness/package.json Bumps @github/copilot used by the E2E harness to a version supporting new elicitation behavior.
test/harness/package-lock.json Locks updated @github/copilot (+ platform packages) for the test harness.
nodejs/test/e2e/ui_elicitation.test.ts Adds E2E coverage for callback-based elicitation capability + multi-client capabilities.changed propagation.
nodejs/test/client.test.ts Adds unit tests asserting requestElicitation flag behavior in session.create.
nodejs/src/types.ts Introduces ElicitationRequest/ElicitationHandler and adds onElicitationRequest to session config types.
nodejs/src/session.ts Registers elicitation handler, listens for elicitation.requested, responds via session.ui.handlePendingElicitation, and applies capabilities.changed updates.
nodejs/src/index.ts Exports new elicitation callback types from the public Node SDK entrypoint.
nodejs/src/client.ts Wires onElicitationRequest registration and sends requestElicitation on create/resume.
nodejs/README.md Documents onElicitationRequest, fan-out behavior, and dynamic capability changes.
nodejs/package.json Bumps SDK dependency on @github/copilot to ^1.0.14-0.
nodejs/package-lock.json Locks updated @github/copilot (+ platform packages) for the Node SDK package.
Files not reviewed (2)
  • nodejs/package-lock.json: Language not supported
  • test/harness/package-lock.json: Language not supported

@github-actions
Copy link
Copy Markdown
Contributor

Cross-SDK Consistency Review

This PR adds elicitation provider support to the Node.js SDK only, enabling SDK clients to act as elicitation providers by handling elicitation.requested broadcast events.

What was added (Node.js SDK):

  • New onElicitationRequest?: ElicitationHandler field in SessionConfig and ResumeSessionConfig
  • ElicitationHandler callback type: (request: ElicitationRequest, invocation: { sessionId: string }) => Promise(ElicitationResult) | ElicitationResult
  • Supporting types: ElicitationRequest, ElicitationResult, ElicitationFieldValue
  • Implementation: session.registerElicitationHandler(), _handleElicitationRequest()
  • RPC: Sends requestElicitation: true flag during session create/resume when handler is provided
  • Event handling: Listens for elicitation.requested broadcast and responds via session.ui.handlePendingElicitation RPC
  • Capabilities tracking: Updates session.capabilities when capabilities.changed events arrive

Cross-SDK Status Check:

Python SDK (python/copilot/session.py):

  • ❌ No on_elicitation_request field in SessionConfig or ResumeSessionConfig
  • Has: on_permission_request, on_user_input_request, but not elicitation provider support

Go SDK (go/types.go):

  • ❌ No OnElicitationRequest field in SessionConfig or ResumeSessionConfig
  • Has: OnPermissionRequest, OnUserInputRequest, but not elicitation provider support

.NET SDK (dotnet/src/Types.cs):

  • ❌ No OnElicitationRequest property in SessionConfig or ResumeSessionConfig
  • Has: OnPermissionRequest, OnUserInputRequest, but not elicitation provider support

Recommendation:

This PR creates a feature gap across the SDKs. The elicitation provider capability enables SDK clients to present form-based UI dialogs on behalf of agents, which is valuable functionality for all SDK users regardless of language.

Suggested follow-up work:

  1. Add equivalent on_elicitation_request / OnElicitationRequest handler to Python SDK
  2. Add equivalent OnElicitationRequest handler to Go SDK
  3. Add equivalent OnElicitationRequest handler to .NET SDK

Each would follow the same pattern as Node.js:

  • Accept a handler callback with signature: (request, invocation) => result
  • Register the handler before session create/resume
  • Send requestElicitation: true (or language-appropriate casing) flag in the RPC
  • Listen for elicitation.requested broadcast events
  • Invoke handler and respond via session.ui.handlePendingElicitation RPC
  • Update capabilities tracking

Note: The generated RPC types (SessionUiHandlePendingElicitationResult, SessionUiHandlePendingElicitationParams) and session events (elicitation.requested) have been generated for all SDKs in this PR, which provides the foundation for implementing this feature in other languages.

This is a valuable feature addition to Node.js! The consistency gap is acceptable as an incremental rollout, but tracking issues should be created to bring this capability to other SDKs soon.

Generated by SDK Consistency Review Agent for issue #908 ·

@MRayermannMSFT MRayermannMSFT force-pushed the mrayermannmsft/elicitation-provider branch from 521a25b to f17ed33 Compare March 30, 2026 20:19
@github-actions
Copy link
Copy Markdown
Contributor

Cross-SDK Consistency Review

This PR adds elicitation provider support to the Node.js SDK, enabling clients to respond to elicitation.requested events and provide form-based UI dialogs. This is a valuable feature, but it creates a cross-language feature parity gap.

Current State

✅ Node.js SDK (this PR):

  • onElicitationRequest handler for acting as an elicitation provider
  • session.capabilities property to check feature support
  • session.ui.* methods (confirm, select, input, elicitation) to request user input
  • ✅ Automatic capabilities.changed event handling
  • ✅ Comprehensive tests and documentation

⚠️ Python, Go, .NET SDKs:

  • ✅ Generated protocol types (SessionUiHandlePendingElicitation, elicitation.requested, capabilities.changed events exist in generated files)
  • No public API to register an elicitation handler (on_elicitation_request / OnElicitationRequest)
  • No session.capabilities property to check feature support
  • No session.ui / session.UI API to make elicitation requests (confirm, select, input)
  • ❌ No automatic handling of capabilities.changed events

Impact

Users of Python, Go, and .NET SDKs cannot:

  1. Act as elicitation providers (the new feature in this PR) - they can't respond to elicitation.requested broadcast events
  2. Make UI elicitation requests (existing Node.js feature) - they can't call session.ui.confirm(), session.ui.select(), etc.
  3. Check session capabilities before calling capability-gated APIs

Recommendation

Consider adding equivalent functionality to Python, Go, and .NET SDKs in follow-up PRs to maintain feature parity:

Python:

session = await client.create_session(
    model="gpt-5",
    on_elicitation_request=async lambda request, invocation: {
        "action": "accept",
        "content": {"field": "value"}
    }
)

# Check capabilities
if session.capabilities.ui and session.capabilities.ui.elicitation:
    result = await session.ui.confirm("Deploy to production?")

Go:

session, _ := client.CreateSession(ctx, &SessionConfig{
    Model: "gpt-5",
    OnElicitationRequest: func(req ElicitationRequest, inv ElicitationInvocation) (ElicitationResult, error) {
        return ElicitationResult{Action: "accept", Content: map[string]any{"field": "value"}}, nil
    },
})

// Check capabilities
if session.Capabilities.UI != nil && session.Capabilities.UI.Elicitation {
    result, _ := session.UI.Confirm(ctx, "Deploy to production?")
}

.NET:

var session = await client.CreateSessionAsync(new SessionConfig {
    Model = "gpt-5",
    OnElicitationRequest = async (request, invocation, ct) => new ElicitationResult {
        Action = "accept",
        Content = new Dictionary(string, object) { ["field"] = "value" }
    }
});

// Check capabilities
if (session.Capabilities?.UI?.Elicitation == true) {
    var result = await session.UI.ConfirmAsync("Deploy to production?");
}

The underlying protocol types are already generated in all SDKs (as evidenced by this PR updating dotnet/src/Generated/Rpc.cs, go/rpc/generated_rpc.go, and python/copilot/generated/rpc.py), so the plumbing exists - it just needs to be exposed as public SDK APIs with the same semantics across languages.

Generated by SDK Consistency Review Agent for issue #908 ·

MackinnonBuck
MackinnonBuck previously approved these changes Mar 30, 2026
Copy link
Copy Markdown
Collaborator

@MackinnonBuck MackinnonBuck left a comment

Choose a reason for hiding this comment

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

Looks great! Just a couple comments, but I won't block the approval based on those.

Another question: What's the motivation for holding off on the Go/.NET/Python changes? Is there a consumer of the Node SDK that needs this change expedited? It would be great to get the other SDKs to match, but this can be done in a follow-up. I'd be happy to handle that if you want someone to take it off your plate.

@MRayermannMSFT
Copy link
Copy Markdown
Contributor Author

Another question: What's the motivation for holding off on the Go/.NET/Python changes? Is there a consumer of the Node SDK that needs this change expedited? It would be great to get the other SDKs to match, but this can be done in a follow-up. I'd be happy to handle that if you want someone to take it off your plate.

Ya, trying to get capabilities land fast for NodeJS for extensions. This is the last thing I need to land. I'll be coming back in a day or so to get other languages landed.

@github-actions
Copy link
Copy Markdown
Contributor

Cross-SDK Consistency Review: Elicitation Provider Support

This PR adds a valuable new feature—elicitation provider support via the onElicitationRequest callback—to the Node.js SDK only. While the implementation is well-designed and thoroughly documented for Node.js, this creates a feature parity gap across the SDK implementations.

What This PR Adds (Node.js Only)

  1. onElicitationRequest callback in SessionConfig and ResumeSessionConfig
  2. Event listener for elicitation.requested broadcast events in the session
  3. Auto-response via RPC using session.ui.handlePendingElicitation
  4. Capability negotiation by sending requestElicitation: true during session create/resume
  5. Dynamic capability updates when capabilities.changed events arrive (other providers join/leave)

Current State of Other SDKs

Generated RPC types exist in all SDKs:

  • Python: SessionUIHandlePendingElicitationParams, session_ui_handle_pending_elicitation()
  • Go: SessionUIHandlePendingElicitationParams, HandlePendingElicitation()
  • .NET: SessionUiHandlePendingElicitationRequest, HandlePendingElicitationAsync()

Generated event types exist in all SDKs:

  • Python: SessionEventType.ELICITATION_REQUESTED
  • Go: SessionEventTypeElicitationRequested
  • .NET: ElicitationRequestedEvent

Missing in Python, Go, and .NET:

  1. Handler callback parameter in session config (e.g., on_elicitation_request, OnElicitationRequest)
  2. Handler registration method (analogous to registerElicitationHandler)
  3. Event listener that invokes the handler when elicitation.requested is received
  4. Capability negotiation flag (requestElicitation) in create/resume RPC
  5. Documentation for this feature

Recommended Next Steps

To maintain cross-language feature parity, consider one of:

Option 1: Expand this PR to add equivalent functionality to Python, Go, and .NET

  • Follow the same pattern used for onUserInputRequest / on_user_input_request / OnUserInputRequest
  • Python: Add on_elicitation_request: ElicitationHandler | None to create_session() and resume_session()
  • Go: Add OnElicitationRequest ElicitationHandler to SessionConfig and ResumeSessionConfig
  • .NET: Add OnElicitationRequest property to SessionConfig and ResumeSessionConfig
  • All: Register handler, listen for elicitation.requested events, invoke handler, send response

Option 2: Track follow-up work in separate issues/PRs

  • Merge Node.js implementation now
  • File tracking issues for Python (#XXX), Go (#XXX), and .NET (#XXX) implementations
  • Reference this PR's implementation as the canonical pattern

Implementation Pattern Reference

For consistency, the implementation in other SDKs should mirror the existing user input handler pattern:

// Node.js (this PR) - pattern to replicate
onElicitationRequest: async (request, invocation) => {
  // request: { message, requestedSchema, mode, elicitationSource, url }
  // invocation: { sessionId }
  return { action: "accept", content: { field: "value" } };
}

All three SDKs already have this pattern for user input:

  • Python: on_user_input_request: UserInputHandler
  • Go: OnUserInputRequest UserInputHandler
  • .NET: OnUserInputRequest property

The elicitation handler would follow the same structure with different parameter types.

Why This Matters

The CLI runtime now supports fan-out elicitation—broadcasting structured input requests to all connected clients. Without SDK support, only the CLI's TUI can respond. By limiting this to Node.js, we prevent Python/Go/.NET SDK users from:

  • Acting as elicitation providers in multi-client scenarios
  • Building headless applications that can present custom UI for MCP server requests
  • Participating in the distributed elicitation workflow

Recommendation: Either expand this PR to include all SDKs, or merge with follow-up issues tracked for the other languages. The generated types are already in place, so the remaining work is registering handlers and wiring up event listeners.

Generated by SDK Consistency Review Agent for issue #908 ·

@MRayermannMSFT MRayermannMSFT added this pull request to the merge queue Mar 30, 2026
Merged via the queue into main with commit 4d26e30 Mar 30, 2026
38 of 39 checks passed
@MRayermannMSFT MRayermannMSFT deleted the mrayermannmsft/elicitation-provider branch March 30, 2026 23:07
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.

3 participants