Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add FluentDialog as a flexible alternative to WaterFallDialog #4864

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

adriand-ghb
Copy link

@adriand-ghb adriand-ghb commented Mar 11, 2025

fixes #4866

Description

The pull request introduces the FluentDialog class, which uses event sourcing to handle complex user interactions in bot applications. This approach allows for an uninterrupted execution flow similar to a durable function.

High-level design

The design leverages JScript's generator functions to separate the conversation flow from the underlying state management.
Behind the scenes, the yield operator in the dialog flow function yields control of the execution thread back to a dialog flow dispatcher. The dispatcher then commits new actions scheduled by the dialog flow (such as starting a child dialog, receiving an activity, or making an async call) to storage. This commit action updates the dialog flow's execution history by appending new events into the dialog state, like an append-only log. When the dialog is later resumed, the dispatcher re-executes the entire function to rebuild the local state. During this replay, if the code tries to begin a child dialog or perform async work, the dispatcher consults the execution history, replays that result, and the function continues to run until it finishes or yields a new suspension task.

Specific Changes

  • Added FluentDialog, related interfaces, and their implementation classes.

Basic Usage

const MAIN_DIALOG = 'MAIN_DIALOG';
const TEXT_PROMPT = 'TEXT_PROMPT'
const CONFIRM_PROMPT = 'CONFIRM_PROMPT'

// Implement the dialog flow function. This example shows a simple Q&A like interaction 
function *dialogFlow(context) {

    let response = yield context.prompt(DIALOG_PROMPT, 'say something');
    yield context.sendActivity(`you said: ${response}`);
        
    let shouldContinue = yield context.prompt(CONFIRM_PROMPT, 'play another round?', ['yes', 'no'])
    if (shouldContinue) {
        yield context.restart();
    }

    yield context.sendActivity('good bye!');
}

// Initialize a DialogSet, passing in a property used to capture state.
const storage = new MemoryStorage();
const convoState = new ConversationState(storage);
const dialogState = convoState.createProperty('dialogState');
const dialogs = new DialogSet(dialogState);

// Add a dialog. Use the included FluentDialog type, initialized with the dialog flow function
dialogs.add(new FluentDialog(MAIN_DIALOG, dialogFlow));
dialogs.add(new TextPrompt(DIALOG_PROMPT));
dialogs.add(new ConfirmPrompt(CONFIRM_PROMPT));

Testing

Unit tests included

Developer Experience

  1. Simplified Dialog Implementation: The FluentDialog provides a straightforward way to define complex conversation flows using a generator function, making the implementation more intuitive.
  2. Event Sourcing: Developers can focus on defining the dialog flow without worrying about state persistence, as the event sourcing mechanism handles it transparently.
  3. Testing: Unit tests included with the PR ensure that the new features are well-tested and reliable, giving developers confidence in using the new dialog type.

* Initial implementation
@adriand-ghb adriand-ghb requested a review from a team as a code owner March 11, 2025 23:18
adriand-ghb

This comment was marked as outdated.

@adriand-ghb
Copy link
Author

@adriand-ghb please read the following Contributor License Agreement(CLA). If you agree with the CLA, please reply with the following information.

@microsoft-github-policy-service agree [company="{your company}"]

Options:

  • (default - no company specified) I have sole ownership of intellectual property rights to my Submissions and I am not making Submissions in the course of work for my employer.
@microsoft-github-policy-service agree
  • (when company given) I am making Submissions in the course of work for my employer (or my employer has intellectual property rights in my Submissions by contract or applicable law). I have permission from my employer to make Submissions and enter into this Agreement on behalf of my employer. By signing below, the defined term “You” includes me and my employer.
@microsoft-github-policy-service agree company="Microsoft"

Contributor License Agreement

@microsoft-github-policy-service agree company="Microsoft"

@adriand-ghb adriand-ghb changed the title Fluent Dialog (#1) feat: Add FluentDialog as a flexible alternative to WaterFallDialog Mar 12, 2025
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.

Add Fluent Dialogs to BotBuilder
2 participants