Skip to content
This repository was archived by the owner on Jan 15, 2025. It is now read-only.

Users/hossein/silence detection #1336

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

Conversation

HSoshiant
Copy link

Adding two new components "TimeoutChoiceInput", and "TimeoutTextInput" to detect the silence while prompting the user.

It's using a timer to track elapsed time and fire in case of reaching threshold

@ghost
Copy link

ghost commented May 17, 2022

CLA assistant check
All CLA requirements met.

Copy link

@arturl arturl left a comment

Choose a reason for hiding this comment

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

Had only one comment so far, more later

//private const string TimeoutId = "this.TimeoutId";
//private const string ActiveTimeoutId = "conversation.ActiveTimeoutId";

private static ConcurrentDictionary<string, (ConcurrentQueue<string> triggeredTimers, IStateMatrix timersState)> conversationStateMatrix = new ConcurrentDictionary<string, (ConcurrentQueue<string> triggeredTimers, IStateMatrix timersState)>();
Copy link

Choose a reason for hiding this comment

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

Will this work in a setup with multiple instances?

Copy link
Author

@HSoshiant HSoshiant May 18, 2022

Choose a reason for hiding this comment

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

By multiple instances means multiple nodes one per region?
I believe each instance is its own app and runs individually and shouldn't affect each other, am I right?

@goldenwitch goldenwitch self-requested a review May 18, 2022 18:15
@goldenwitch
Copy link
Contributor

We need the readme to get updated.

/// <summary>
/// The middleware that handles all outgoing messages
/// </summary>
public class SetSpeakMiddleware : IMiddleware
Copy link
Contributor

Choose a reason for hiding this comment

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

Copy and paste error?

"$schema": "https://schemas.botframework.com/schemas/component/v1.0/component.schema",
"$role": [ "implements(Microsoft.IDialog)", "extends(Microsoft.InputDialog)" ],
"type": "object",
"title": "(Preview)1 text input dialog with silence detection",
Copy link
Contributor

Choose a reason for hiding this comment

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

Style: Capitalize, use non-digit version of number.

Copy link
Author

Choose a reason for hiding this comment

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

Fixed

"$role": [ "implements(Microsoft.IDialog)", "extends(Microsoft.InputDialog)" ],
"type": "object",
"title": "(Preview)1 text input dialog with silence detection",
"description": "getting arbitrary text and detecting silence in case of no entry",
Copy link
Contributor

Choose a reason for hiding this comment

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

Grab the description from the existing TextInput

Copy link
Author

Choose a reason for hiding this comment

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

Fixed.

"defaultValue": {
"$ref": "schema:#/definitions/stringExpression",
"title": "Default value",
"description": "'Property' will be set to the value of this expression when max turn count is exceeded.",
Copy link
Contributor

Choose a reason for hiding this comment

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

Does TextInput have a max turn count? Is this default value only available on silence?

Copy link
Author

@HSoshiant HSoshiant May 19, 2022

Choose a reason for hiding this comment

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

MaxTurn is used only for invalid inputs
However in case of Detected Silence , as a hack, we set the max turn to one to force the component to continue and that will set the value to the default before proceeding

Copy link
Author

Choose a reason for hiding this comment

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

Also I cloned this file from Microsoft.Bot.Builder.Dialogs.Adaptive\Schemas\Dialogs\Microsoft.TextInput.schema

@@ -18,6 +19,10 @@ public class TelephonyBotComponent : BotComponent
public override void ConfigureServices(IServiceCollection services, IConfiguration configuration)
{
// Conditionals
var middleware = new Middleware.SetSpeakMiddleware();
services.AddSingleton<IMiddleware>(middleware);
middleware.addEventReceiver(ActivityTypes.EndOfConversation, TimeoutInput.RemoveTimers);
Copy link
Contributor

Choose a reason for hiding this comment

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

Does this middleware actually get correctly registered? I believe this DI entry point is special and won't be able to register middleware.

Copy link
Author

Choose a reason for hiding this comment

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

Seems working and get registered

@@ -51,6 +52,8 @@
<None Remove="Schemas\Microsoft.Telephony.ResumeRecording.uischema" />
<None Remove="Schemas\Microsoft.Telephony.TimeoutChoiceInput.schema" />
<None Remove="Schemas\Microsoft.Telephony.TimeoutChoiceInput.uischema" />
<None Remove="Schemas\Microsoft.Telephony.TimeoutTextInput.schema" />
Copy link
Contributor

Choose a reason for hiding this comment

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

Style: spacing

Copy link
Author

Choose a reason for hiding this comment

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

fixed


private static ConcurrentDictionary<string, (ConcurrentQueue<string> triggeredTimers, IStateMatrix timersState)> conversationStateMatrix = new ConcurrentDictionary<string, (ConcurrentQueue<string> triggeredTimers, IStateMatrix timersState)>();

public static async Task<DialogTurnResult> BeginDialogAsync<K>(K inputActivity, DialogContext dc,
Copy link
Contributor

Choose a reason for hiding this comment

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

Style: Prefer T over K

return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false);
}

dc.State.SetValue(ITimeoutInput.SilenceDetected, false);
Copy link
Contributor

Choose a reason for hiding this comment

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

What do you think, is this property more discoverable here, or on the interface? I generally don't expect interfaces to know things.

Copy link
Author

Choose a reason for hiding this comment

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

I agree but to reduce the redundancies and having it in both TimeoutChoiceInput and TimeoutTextInput (as they don't derived from a same base class) I thought we can use interface to carry it and reduce rewriting.
Also the main problem would be when we pass them into TimeoutInput as a single controller for both!

//-----------------------------Body---------------
var activity = dc.Context.Activity;

//we have to manage our timer somehow.
Copy link
Contributor

Choose a reason for hiding this comment

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

Are these comments still valid?

Copy link
Author

Choose a reason for hiding this comment

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

Removed. Thanks

@goldenwitch
Copy link
Contributor

Also, could probably use some tests, at least to validate/explain what the middleware should do

@tracyboehrer
Copy link
Member

Is this still a thing or can it be closed?

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants