Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Nov 17, 2025

Return InteractionReference from IInteractionService methods

This PR implements the feature request to return a reference from IInteractionService methods before the result is available.

Changes completed:

  • Create new InteractionReference<TResult> class (renamed from Interaction<TResult>) that wraps a Task and provides:
    • Id property - unique identifier matching Interaction.InteractionId
    • GetResultAsync() method to get the result
    • Cancel() method to cancel the interaction
    • GetAwaiter() to support await directly on the InteractionReference object
    • ConfigureAwait() for configuration
    • IsCompleted property to check completion status
    • DebuggerDisplayAttribute showing Id and IsCompleted
    • Public constructor accepting id, resultTask, and cancellationTokenSource
  • Update IInteractionService interface methods to return InteractionReference<T> instead of Task<InteractionResult<T>>
  • Update InteractionService implementation to:
    • Create Interaction instances synchronously before creating InteractionReference
    • Pass Interaction.InteractionId to InteractionReference constructor
    • Return InteractionReference<T> instances with matching IDs
  • Update TestInteractionService implementations to return InteractionReference<T> instances
  • Remove DefaultTimeout extension methods for InteractionReference<T> - callers use reference.GetResultAsync().DefaultTimeout() instead
  • Fix test assertions to properly await InteractionReference<T> objects using GetResultAsync().DefaultTimeout()
  • Fix playground stress app to work with new return type
  • Fix DevTunnels test service implementation
  • Full solution builds successfully

Technical approach:

The InteractionReference<TResult> class implements the awaitable pattern so existing code that uses await can continue to work with minimal changes. The class wraps the underlying task and provides additional control methods like Cancel().

The Interaction is now created synchronously at the start of each prompt method, ensuring the ID is available immediately. This ID is then passed to the InteractionReference constructor, guaranteeing that InteractionReference.Id matches Interaction.InteractionId.

New API allows developers to:

  1. Get a reference to the interaction immediately when calling a prompt method
  2. Access the unique interaction ID via the Id property (matches Interaction.InteractionId)
  3. Check if the interaction is completed using IsCompleted property
  4. Cancel the interaction using the Cancel() method
  5. Await the interaction directly to get the result
  6. Get the underlying task via GetResultAsync() for advanced scenarios

Example usage:

// Get reference immediately
var interaction = interactionService.PromptConfirmationAsync("Title", "Message");

// Access the unique ID (same as Interaction.InteractionId)
Console.WriteLine($"Interaction ID: {interaction.Id}");

// Check completion status
if (!interaction.IsCompleted)
{
    // Can cancel if needed
    interaction.Cancel();
}

// Await to get the result
var result = await interaction;

// Or get the task explicitly for advanced scenarios
var resultTask = interaction.GetResultAsync();

Breaking change note:

This changes the return type of IInteractionService methods from Task<InteractionResult<T>> to InteractionReference<T>. The InteractionReference class is awaitable, so existing code using await will continue to work. Code that explicitly typed variables as Task<InteractionResult<T>> will need to change to InteractionReference<T> or use var.

Implementation complete

All changes have been implemented and the full solution builds successfully.

Fixes #13015

Original prompt

This section details on the original issue you should resolve

<issue_title>Return reference from interaction service methods</issue_title>
<issue_description>### Is there an existing issue for this?

  • I have searched the existing issues

Is your feature request related to a problem? Please describe the problem.

IInteractionService methods like PromptInputsAsync return a task that is completed with the result. There maybe scenarios where it's useful to have a reference to the interaction prompt before the result is returned.

Describe the solution you'd like

Task<InteractionResult<InteractionInputCollection>> PromptInputsAsync(...) could be changed to Interaction<InteractionInputCollection> PromptInputs(...)

And Interaction<TResult> looks like this:

public sealed class Interaction<TResult>
{
    public Task<InteractionResult<TResult>> GetResultAsync()
    public void Cancel() 
    public TaskAwaiter<TResponse> GetAwaiter()
    public ConfiguredTaskAwaitable<TResponse> ConfigureAwait(bool continueOnCapturedContext)
}

Other methods would follow a similar pattern.

Additional context

No response</issue_description>

Comments on the Issue (you are @copilot in this section)


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI and others added 4 commits November 17, 2025 23:29
Co-authored-by: JamesNK <303201+JamesNK@users.noreply.github.com>
…assertions

Co-authored-by: JamesNK <303201+JamesNK@users.noreply.github.com>
Co-authored-by: JamesNK <303201+JamesNK@users.noreply.github.com>
Co-authored-by: JamesNK <303201+JamesNK@users.noreply.github.com>
Copilot AI changed the title [WIP] Return reference from interaction service methods Return Interaction<T> reference from IInteractionService methods Nov 18, 2025
Copilot AI requested a review from JamesNK November 18, 2025 00:02
Copilot finished work on behalf of JamesNK November 18, 2025 00:02
@JamesNK
Copy link
Member

JamesNK commented Nov 18, 2025

@copilot Rename Interaction to InteractionReference. Add id to reference. Add debuggerdisplayattribute to reference.

… DebuggerDisplayAttribute

Co-authored-by: JamesNK <303201+JamesNK@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Nov 18, 2025

@copilot Rename Interaction to InteractionReference. Add id to reference. Add debuggerdisplayattribute to reference.

Done in 675f44f. The class has been renamed to InteractionReference<T>, an Id property has been added with auto-incrementing values, and DebuggerDisplayAttribute has been added showing both Id and IsCompleted.

Copilot AI changed the title Return Interaction<T> reference from IInteractionService methods Return InteractionReference from IInteractionService methods Nov 18, 2025
Copilot finished work on behalf of JamesNK November 18, 2025 00:37
… GetResultAsync().DefaultTimeout() instead

Co-authored-by: JamesNK <303201+JamesNK@users.noreply.github.com>
Copilot AI requested a review from JamesNK November 18, 2025 01:19
Copilot finished work on behalf of JamesNK November 18, 2025 01:19
@JamesNK
Copy link
Member

JamesNK commented Nov 18, 2025

@copilot Id on the reference should be the same value as Interaction.InteractionId

…ctionId

Co-authored-by: JamesNK <303201+JamesNK@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Nov 18, 2025

@copilot Id on the reference should be the same value as Interaction.InteractionId

Done in 9daddc3. The InteractionReference<T> constructor now accepts the interaction ID as a parameter. The Interaction is created synchronously at the start of each prompt method, and its InteractionId is passed to the InteractionReference constructor, ensuring InteractionReference.Id matches Interaction.InteractionId.

Copilot finished work on behalf of JamesNK November 18, 2025 02:15
@JamesNK
Copy link
Member

JamesNK commented Nov 18, 2025

@davidfowl @mitchdenny @captainsafia @eerhardt

What do you think of the interaction service returning an object that can act as a reference? I'm thinking about the situation where you want to link prompts together.

var page1 = interactionService.PromptInputsAsync(inputs1);
var page2 = interactionService.PromptInputsAsync(inputs2, options: new { ShowAfterInteraction = page1 });

await page1;
await page2;

It's a pretty niche scenario. But something to think about before making the API non-experimental.

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.

Return reference from interaction service methods

2 participants