Skip to content

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
@tracyboehrer
Copy link
Member

@adriand-ghb Thanks so much for your submission and apologies for the delay. We are no longer adding features to Bot Framework SDK in preference to Agents SDK. Check it out at https://github.com/microsoft/agents-for-js

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

3 participants