Merge branch 'master' into add/twilio-functional-tests
This commit is contained in:
Коммит
9508da6912
|
@ -1,6 +1,9 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- File name extension must be .runsettings -->
|
||||
<RunSettings>
|
||||
<RunConfiguration>
|
||||
<MaxCpuCount>10</MaxCpuCount>
|
||||
</RunConfiguration>
|
||||
<DataCollectionRunSettings>
|
||||
<DataCollectors>
|
||||
<DataCollector friendlyName="Code Coverage" uri="datacollector://Microsoft/CodeCoverage/2.0" assemblyQualifiedName="Microsoft.VisualStudio.Coverage.DynamicCoverageDataCollector, Microsoft.VisualStudio.TraceCollector, Version=11.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
|
|
|
@ -6,12 +6,16 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Libraries", "Libraries", "{
|
|||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{AD743B78-D61F-4FBF-B620-FA83CE599A50}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Bot.Builder.Dialogs.Adaptive", "libraries\Microsoft.Bot.Builder.Dialogs.Adaptive\Microsoft.Bot.Builder.Dialogs.Adaptive.csproj", "{3CF175CF-1AF4-4109-96CB-221684DCED7D}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Bot.Builder.Dialogs.Adaptive.Tests", "tests\Microsoft.Bot.Builder.Dialogs.Adaptive.Tests\Microsoft.Bot.Builder.Dialogs.Adaptive.Tests.csproj", "{CA008713-655E-46DA-BBDF-1EF6B8CE7DCA}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Bot.Builder.Azure.Tests", "tests\Microsoft.Bot.Builder.Azure.Tests\Microsoft.Bot.Builder.Azure.Tests.csproj", "{E325A0E2-716A-49E0-9767-5087CF05727C}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Bot.Builder.Azure", "libraries\Microsoft.Bot.Builder.Azure\Microsoft.Bot.Builder.Azure.csproj", "{B2C5EED9-21B2-4763-AB92-C1995B76DA3A}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Bot.Builder.AI.QnA.Tests", "tests\Microsoft.Bot.Builder.AI.QnA.Tests\Microsoft.Bot.Builder.AI.QnA.Tests.csproj", "{9BDF7020-A19F-4C6C-B329-E4BFEFF6DE6B}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Bot.Builder.Azure.Tests", "tests\Microsoft.Bot.Builder.Azure.Tests\Microsoft.Bot.Builder.Azure.Tests.csproj", "{E325A0E2-716A-49E0-9767-5087CF05727C}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Bot.Connector", "libraries\Microsoft.Bot.Connector\Microsoft.Bot.Connector.csproj", "{6462DA5D-27DC-4CD5-9467-5EFB998FD838}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Bot.Schema", "libraries\Microsoft.Bot.Schema\Microsoft.Bot.Schema.csproj", "{C1F54CDC-AD1D-45BB-8F7D-F49E411AFAF1}"
|
||||
|
@ -76,10 +80,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Bot.Builder.TestB
|
|||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Bot.Builder.Dialogs.Declarative", "libraries\Microsoft.Bot.Builder.Dialogs.Declarative\Microsoft.Bot.Builder.Dialogs.Declarative.csproj", "{1BC05915-044E-4776-8956-B44BBEFF2F84}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Bot.Builder.Dialogs.Adaptive", "libraries\Microsoft.Bot.Builder.Dialogs.Adaptive\Microsoft.Bot.Builder.Dialogs.Adaptive.csproj", "{3CF175CF-1AF4-4109-96CB-221684DCED7D}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Bot.Builder.Dialogs.Adaptive.Tests", "tests\Microsoft.Bot.Builder.Dialogs.Adaptive.Tests\Microsoft.Bot.Builder.Dialogs.Adaptive.Tests.csproj", "{CA008713-655E-46DA-BBDF-1EF6B8CE7DCA}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Bot.Expressions.Tests", "tests\Microsoft.Bot.Expressions.Tests\Microsoft.Bot.Expressions.Tests.csproj", "{AE3FC7F6-B212-4438-B1D7-C121BB4C15ED}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Bot.Expressions", "libraries\Microsoft.Bot.Expressions\Microsoft.Bot.Expressions.csproj", "{8DC1257B-7650-40EB-97A2-C1CBA306DA6A}"
|
||||
|
@ -178,6 +178,30 @@ Global
|
|||
Release-Windows|Any CPU = Release-Windows|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{3CF175CF-1AF4-4109-96CB-221684DCED7D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{3CF175CF-1AF4-4109-96CB-221684DCED7D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{3CF175CF-1AF4-4109-96CB-221684DCED7D}.Debug-Windows|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{3CF175CF-1AF4-4109-96CB-221684DCED7D}.Debug-Windows|Any CPU.Build.0 = Debug|Any CPU
|
||||
{3CF175CF-1AF4-4109-96CB-221684DCED7D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{3CF175CF-1AF4-4109-96CB-221684DCED7D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{3CF175CF-1AF4-4109-96CB-221684DCED7D}.Release-Windows|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{3CF175CF-1AF4-4109-96CB-221684DCED7D}.Release-Windows|Any CPU.Build.0 = Release|Any CPU
|
||||
{CA008713-655E-46DA-BBDF-1EF6B8CE7DCA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{CA008713-655E-46DA-BBDF-1EF6B8CE7DCA}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{CA008713-655E-46DA-BBDF-1EF6B8CE7DCA}.Debug-Windows|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{CA008713-655E-46DA-BBDF-1EF6B8CE7DCA}.Debug-Windows|Any CPU.Build.0 = Debug|Any CPU
|
||||
{CA008713-655E-46DA-BBDF-1EF6B8CE7DCA}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{CA008713-655E-46DA-BBDF-1EF6B8CE7DCA}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{CA008713-655E-46DA-BBDF-1EF6B8CE7DCA}.Release-Windows|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{CA008713-655E-46DA-BBDF-1EF6B8CE7DCA}.Release-Windows|Any CPU.Build.0 = Release|Any CPU
|
||||
{E325A0E2-716A-49E0-9767-5087CF05727C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{E325A0E2-716A-49E0-9767-5087CF05727C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{E325A0E2-716A-49E0-9767-5087CF05727C}.Debug-Windows|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{E325A0E2-716A-49E0-9767-5087CF05727C}.Debug-Windows|Any CPU.Build.0 = Debug|Any CPU
|
||||
{E325A0E2-716A-49E0-9767-5087CF05727C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{E325A0E2-716A-49E0-9767-5087CF05727C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{E325A0E2-716A-49E0-9767-5087CF05727C}.Release-Windows|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{E325A0E2-716A-49E0-9767-5087CF05727C}.Release-Windows|Any CPU.Build.0 = Release|Any CPU
|
||||
{B2C5EED9-21B2-4763-AB92-C1995B76DA3A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{B2C5EED9-21B2-4763-AB92-C1995B76DA3A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{B2C5EED9-21B2-4763-AB92-C1995B76DA3A}.Debug-Windows|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
|
@ -194,14 +218,6 @@ Global
|
|||
{9BDF7020-A19F-4C6C-B329-E4BFEFF6DE6B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{9BDF7020-A19F-4C6C-B329-E4BFEFF6DE6B}.Release-Windows|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{9BDF7020-A19F-4C6C-B329-E4BFEFF6DE6B}.Release-Windows|Any CPU.Build.0 = Release|Any CPU
|
||||
{E325A0E2-716A-49E0-9767-5087CF05727C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{E325A0E2-716A-49E0-9767-5087CF05727C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{E325A0E2-716A-49E0-9767-5087CF05727C}.Debug-Windows|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{E325A0E2-716A-49E0-9767-5087CF05727C}.Debug-Windows|Any CPU.Build.0 = Debug|Any CPU
|
||||
{E325A0E2-716A-49E0-9767-5087CF05727C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{E325A0E2-716A-49E0-9767-5087CF05727C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{E325A0E2-716A-49E0-9767-5087CF05727C}.Release-Windows|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{E325A0E2-716A-49E0-9767-5087CF05727C}.Release-Windows|Any CPU.Build.0 = Release|Any CPU
|
||||
{6462DA5D-27DC-4CD5-9467-5EFB998FD838}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{6462DA5D-27DC-4CD5-9467-5EFB998FD838}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{6462DA5D-27DC-4CD5-9467-5EFB998FD838}.Debug-Windows|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
|
@ -426,22 +442,6 @@ Global
|
|||
{1BC05915-044E-4776-8956-B44BBEFF2F84}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{1BC05915-044E-4776-8956-B44BBEFF2F84}.Release-Windows|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{1BC05915-044E-4776-8956-B44BBEFF2F84}.Release-Windows|Any CPU.Build.0 = Release|Any CPU
|
||||
{3CF175CF-1AF4-4109-96CB-221684DCED7D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{3CF175CF-1AF4-4109-96CB-221684DCED7D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{3CF175CF-1AF4-4109-96CB-221684DCED7D}.Debug-Windows|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{3CF175CF-1AF4-4109-96CB-221684DCED7D}.Debug-Windows|Any CPU.Build.0 = Debug|Any CPU
|
||||
{3CF175CF-1AF4-4109-96CB-221684DCED7D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{3CF175CF-1AF4-4109-96CB-221684DCED7D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{3CF175CF-1AF4-4109-96CB-221684DCED7D}.Release-Windows|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{3CF175CF-1AF4-4109-96CB-221684DCED7D}.Release-Windows|Any CPU.Build.0 = Release|Any CPU
|
||||
{CA008713-655E-46DA-BBDF-1EF6B8CE7DCA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{CA008713-655E-46DA-BBDF-1EF6B8CE7DCA}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{CA008713-655E-46DA-BBDF-1EF6B8CE7DCA}.Debug-Windows|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{CA008713-655E-46DA-BBDF-1EF6B8CE7DCA}.Debug-Windows|Any CPU.Build.0 = Debug|Any CPU
|
||||
{CA008713-655E-46DA-BBDF-1EF6B8CE7DCA}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{CA008713-655E-46DA-BBDF-1EF6B8CE7DCA}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{CA008713-655E-46DA-BBDF-1EF6B8CE7DCA}.Release-Windows|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{CA008713-655E-46DA-BBDF-1EF6B8CE7DCA}.Release-Windows|Any CPU.Build.0 = Release|Any CPU
|
||||
{AE3FC7F6-B212-4438-B1D7-C121BB4C15ED}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{AE3FC7F6-B212-4438-B1D7-C121BB4C15ED}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{AE3FC7F6-B212-4438-B1D7-C121BB4C15ED}.Debug-Windows|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
|
@ -695,9 +695,11 @@ Global
|
|||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{3CF175CF-1AF4-4109-96CB-221684DCED7D} = {4269F3C3-6B42-419B-B64A-3E6DC0F1574A}
|
||||
{CA008713-655E-46DA-BBDF-1EF6B8CE7DCA} = {AD743B78-D61F-4FBF-B620-FA83CE599A50}
|
||||
{E325A0E2-716A-49E0-9767-5087CF05727C} = {AD743B78-D61F-4FBF-B620-FA83CE599A50}
|
||||
{B2C5EED9-21B2-4763-AB92-C1995B76DA3A} = {4269F3C3-6B42-419B-B64A-3E6DC0F1574A}
|
||||
{9BDF7020-A19F-4C6C-B329-E4BFEFF6DE6B} = {AD743B78-D61F-4FBF-B620-FA83CE599A50}
|
||||
{E325A0E2-716A-49E0-9767-5087CF05727C} = {AD743B78-D61F-4FBF-B620-FA83CE599A50}
|
||||
{6462DA5D-27DC-4CD5-9467-5EFB998FD838} = {4269F3C3-6B42-419B-B64A-3E6DC0F1574A}
|
||||
{C1F54CDC-AD1D-45BB-8F7D-F49E411AFAF1} = {4269F3C3-6B42-419B-B64A-3E6DC0F1574A}
|
||||
{ADA8AB8B-2066-4193-B8F7-985669B23E00} = {4269F3C3-6B42-419B-B64A-3E6DC0F1574A}
|
||||
|
@ -729,8 +731,6 @@ Global
|
|||
{E4E13301-9193-4106-B0E3-41276B478E7C} = {AD743B78-D61F-4FBF-B620-FA83CE599A50}
|
||||
{76391566-9F22-4994-8B0F-02EFC0E9E228} = {AD743B78-D61F-4FBF-B620-FA83CE599A50}
|
||||
{1BC05915-044E-4776-8956-B44BBEFF2F84} = {4269F3C3-6B42-419B-B64A-3E6DC0F1574A}
|
||||
{3CF175CF-1AF4-4109-96CB-221684DCED7D} = {4269F3C3-6B42-419B-B64A-3E6DC0F1574A}
|
||||
{CA008713-655E-46DA-BBDF-1EF6B8CE7DCA} = {AD743B78-D61F-4FBF-B620-FA83CE599A50}
|
||||
{AE3FC7F6-B212-4438-B1D7-C121BB4C15ED} = {AD743B78-D61F-4FBF-B620-FA83CE599A50}
|
||||
{8DC1257B-7650-40EB-97A2-C1CBA306DA6A} = {4269F3C3-6B42-419B-B64A-3E6DC0F1574A}
|
||||
{D5E70443-4BA2-42ED-992A-010268440B08} = {AD743B78-D61F-4FBF-B620-FA83CE599A50}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
|
||||
# ![Bot Framework for dotnet](./doc/media/BotFrameworkDotnet_header.png)
|
||||
|
||||
### [Click here to find out what's new with Bot Framework](https://github.com/Microsoft/botframework/blob/master/whats-new.md#whats-new)
|
||||
### [Click here to find out what's new with Bot Framework](https://docs.microsoft.com/en-us/azure/bot-service/what-is-new?view=azure-bot-service-4.0)
|
||||
|
||||
# Bot Framework SDK v4 for .NET
|
||||
This repository contains code for the .NET version of the [Microsoft Bot Framework SDK](https://github.com/Microsoft/botbuilder). The Bot Framework SDK v4 enable developers to model conversation and build sophisticated bot applications using .NET.
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU' ">
|
||||
<DocumentationFile>bin\$(Configuration)\netstandard2.0\Microsoft.Bot.Builder.Adapters.Facebook.xml</DocumentationFile>
|
||||
<DocumentationFile>bin\$(Configuration)\$(TargetFramework)\Microsoft.Bot.Builder.Adapters.Facebook.xml</DocumentationFile>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
<WarningsAsErrors />
|
||||
</PropertyGroup>
|
||||
|
@ -29,7 +29,9 @@
|
|||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Bot.Builder.Integration.AspNet.Core" Condition=" '$(IsBuildServer)' == '' " Version="4.8.0-local" />
|
||||
<PackageReference Include="Microsoft.Bot.Builder.Integration.AspNet.Core" Condition=" '$(IsBuildServer)' != '' " Version="$(ReleasePackageVersion)" />
|
||||
<PackageReference Include="SourceLink.Create.CommandLine" Version="2.8.3" />
|
||||
<PackageReference Include="SourceLink.Create.CommandLine" Version="2.8.3" >
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DocumentationFile>bin\$(Configuration)\netstandard2.0\Microsoft.Bot.Builder.Adapters.Slack.xml</DocumentationFile>
|
||||
<DocumentationFile>bin\$(Configuration)\$(TargetFramework)\Microsoft.Bot.Builder.Adapters.Slack.xml</DocumentationFile>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
<WarningsAsErrors />
|
||||
</PropertyGroup>
|
||||
|
@ -31,7 +31,9 @@
|
|||
<ItemGroup>
|
||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
||||
<PackageReference Include="SlackAPI" Version="1.1.2" />
|
||||
<PackageReference Include="SourceLink.Create.CommandLine" Version="2.8.3" />
|
||||
<PackageReference Include="SourceLink.Create.CommandLine" Version="2.8.3" >
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.Bot.Builder.Integration.AspNet.Core" Condition=" '$(IsBuildServer)' == '' " Version="4.8.0-local" />
|
||||
<PackageReference Include="Microsoft.Bot.Builder.Integration.AspNet.Core" Condition=" '$(IsBuildServer)' != '' " Version="$(ReleasePackageVersion)" />
|
||||
</ItemGroup>
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU' ">
|
||||
<DocumentationFile>bin\$(Configuration)\netstandard2.0\Microsoft.Bot.Builder.Adapters.Twilio.xml</DocumentationFile>
|
||||
<DocumentationFile>bin\$(Configuration)\$(TargetFramework)\Microsoft.Bot.Builder.Adapters.Twilio.xml</DocumentationFile>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
<WarningsAsErrors />
|
||||
</PropertyGroup>
|
||||
|
@ -36,7 +36,9 @@
|
|||
<PackageReference Include="Twilio" Version="5.33.1" />
|
||||
<PackageReference Include="Microsoft.Bot.Builder.Integration.AspNet.Core" Condition=" '$(IsBuildServer)' == '' " Version="4.8.0-local" />
|
||||
<PackageReference Include="Microsoft.Bot.Builder.Integration.AspNet.Core" Condition=" '$(IsBuildServer)' != '' " Version="$(ReleasePackageVersion)" />
|
||||
<PackageReference Include="SourceLink.Create.CommandLine" Version="2.8.3" />
|
||||
<PackageReference Include="SourceLink.Create.CommandLine" Version="2.8.3" >
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU' ">
|
||||
<DocumentationFile>bin\$(Configuration)\netstandard2.0\Microsoft.Bot.Builder.Adapters.Webex.xml</DocumentationFile>
|
||||
<DocumentationFile>bin\$(Configuration)\$(TargetFramework)\Microsoft.Bot.Builder.Adapters.Webex.xml</DocumentationFile>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
<WarningsAsErrors />
|
||||
</PropertyGroup>
|
||||
|
@ -32,7 +32,9 @@
|
|||
<PackageReference Include="Thrzn41.WebexTeams" Version="1.6.2" />
|
||||
<PackageReference Include="Microsoft.Bot.Builder.Integration.AspNet.Core" Condition=" '$(IsBuildServer)' == '' " Version="4.8.0-local" />
|
||||
<PackageReference Include="Microsoft.Bot.Builder.Integration.AspNet.Core" Condition=" '$(IsBuildServer)' != '' " Version="$(ReleasePackageVersion)" />
|
||||
<PackageReference Include="SourceLink.Create.CommandLine" Version="2.8.3" />
|
||||
<PackageReference Include="SourceLink.Create.CommandLine" Version="2.8.3" >
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
@ -48,7 +48,6 @@ namespace Microsoft.Bot.Builder.AI.Luis
|
|||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="LuisRecognizer"/> class.
|
||||
/// </summary>
|
||||
/// <param name="application">The LUIS application to use to recognize text.</param>
|
||||
/// <param name="recognizerOptions"> The LUIS recognizer version options.</param>
|
||||
/// <param name="clientHandler">(Optional) Custom handler for LUIS API calls to allow mocking.</param>
|
||||
public LuisRecognizer(LuisRecognizerOptions recognizerOptions, HttpClientHandler clientHandler = null)
|
||||
|
|
|
@ -34,7 +34,9 @@
|
|||
<ItemGroup>
|
||||
<PackageReference Include="AsyncUsageAnalyzers" Version="1.0.0-alpha003" PrivateAssets="all" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
||||
<PackageReference Include="SourceLink.Create.CommandLine" Version="2.8.3" />
|
||||
<PackageReference Include="SourceLink.Create.CommandLine" Version="2.8.3" >
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.Azure.CognitiveServices.Language.LUIS.Runtime" Version="2.1.0" />
|
||||
<PackageReference Include="Microsoft.Bot.Schema" Condition=" '$(IsBuildServer)' == '' " Version="4.8.0-local" />
|
||||
<PackageReference Include="Microsoft.Bot.Schema" Condition=" '$(IsBuildServer)' != '' " Version="$(ReleasePackageVersion)" />
|
||||
|
|
|
@ -38,7 +38,9 @@
|
|||
<PackageReference Include="Microsoft.Bot.Configuration" Condition=" '$(IsBuildServer)' != '' " Version="$(ReleasePackageVersion)" />
|
||||
<PackageReference Include="Microsoft.Bot.Builder.Dialogs" Condition=" '$(IsBuildServer)' == '' " Version="4.8.0-local" />
|
||||
<PackageReference Include="Microsoft.Bot.Builder.Dialogs" Condition=" '$(IsBuildServer)' != '' " Version="$(ReleasePackageVersion)" />
|
||||
<PackageReference Include="SourceLink.Create.CommandLine" Version="2.8.3" />
|
||||
<PackageReference Include="SourceLink.Create.CommandLine" Version="2.8.3" >
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
@ -29,7 +29,9 @@
|
|||
<PackageReference Include="Microsoft.ApplicationInsights" Version="2.8.1" />
|
||||
<PackageReference Include="Microsoft.Bot.Builder" Condition=" '$(IsBuildServer)' == '' " Version="4.8.0-local" />
|
||||
<PackageReference Include="Microsoft.Bot.Builder" Condition=" '$(IsBuildServer)' != '' " Version="$(ReleasePackageVersion)" />
|
||||
<PackageReference Include="SourceLink.Create.CommandLine" Version="2.8.3" />
|
||||
<PackageReference Include="SourceLink.Create.CommandLine" Version="2.8.3" >
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
@ -51,7 +51,9 @@
|
|||
<PackageReference Include="Microsoft.Azure.DocumentDB.Core" Version="2.1.2" />
|
||||
<PackageReference Include="Microsoft.Azure.Storage.Blob" Version="9.4.2" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
||||
<PackageReference Include="SourceLink.Create.CommandLine" Version="2.8.3" />
|
||||
<PackageReference Include="SourceLink.Create.CommandLine" Version="2.8.3" >
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="System.Threading.Tasks.Extensions" Version="4.5.1" />
|
||||
<PackageReference Include="Microsoft.Bot.Builder" Condition=" '$(IsBuildServer)' == '' " Version="4.8.0-local" />
|
||||
<PackageReference Include="Microsoft.Bot.Builder" Condition=" '$(IsBuildServer)' != '' " Version="$(ReleasePackageVersion)" />
|
||||
|
|
|
@ -49,8 +49,10 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
return await OnActionScopeResultAsync(dc, actionScopeResult, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
var dcState = dc.GetState();
|
||||
|
||||
// When we are resumed, we increment our offset into the actions and being the next action
|
||||
var nextOffset = dc.GetState().GetIntValue(OFFSETKEY, 0) + 1;
|
||||
var nextOffset = dcState.GetIntValue(OFFSETKEY, 0) + 1;
|
||||
if (nextOffset < this.Actions.Count)
|
||||
{
|
||||
return await this.BeginActionAsync(dc, nextOffset, cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
|
@ -135,7 +137,9 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
protected virtual async Task<DialogTurnResult> BeginActionAsync(DialogContext dc, int offset, CancellationToken cancellationToken = default)
|
||||
{
|
||||
// get the action for the offset
|
||||
dc.GetState().SetValue(OFFSETKEY, offset);
|
||||
var dcState = dc.GetState();
|
||||
|
||||
dcState.SetValue(OFFSETKEY, offset);
|
||||
var actionId = this.Actions[offset].Id;
|
||||
|
||||
// begin Action dialog
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using Microsoft.Bot.Builder.Dialogs.Declarative;
|
||||
using Microsoft.Bot.Expressions;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
@ -16,12 +17,13 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
public abstract class BaseInvokeDialog : Dialog, IDialogDependencies
|
||||
{
|
||||
// Expression for dialogId to call (allowing dynamic expression)
|
||||
private string dialogIdToCall;
|
||||
|
||||
public BaseInvokeDialog(string dialogIdToCall = null, IDictionary<string, string> bindingOptions = null)
|
||||
public BaseInvokeDialog(string dialogIdToCall = null, object bindingOptions = null)
|
||||
: base()
|
||||
{
|
||||
this.dialogIdToCall = dialogIdToCall;
|
||||
if (dialogIdToCall != null)
|
||||
{
|
||||
this.Dialog = dialogIdToCall;
|
||||
}
|
||||
|
||||
if (bindingOptions != null)
|
||||
{
|
||||
|
@ -36,7 +38,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
/// Configurable options for the dialog.
|
||||
/// </value>
|
||||
[JsonProperty("options")]
|
||||
public object Options { get; set; } = new JObject();
|
||||
public ObjectExpression<object> Options { get; set; } = new ObjectExpression<object>();
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the dialog to call.
|
||||
|
@ -45,7 +47,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
/// The dialog to call.
|
||||
/// </value>
|
||||
[JsonProperty("dialog")]
|
||||
public Dialog Dialog { get; set; }
|
||||
public DialogExpression Dialog { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether to have the new dialog should process the activity.
|
||||
|
@ -53,13 +55,13 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
/// <value>The default for this will be true, which means the new dialog should not look the activity. You can set this to false to dispatch the activity to the new dialog.</value>
|
||||
[DefaultValue(true)]
|
||||
[JsonProperty("activityProcessed")]
|
||||
public bool ActivityProcessed { get; set; } = true;
|
||||
public BoolExpression ActivityProcessed { get; set; } = true;
|
||||
|
||||
public virtual IEnumerable<Dialog> GetDependencies()
|
||||
{
|
||||
if (Dialog != null)
|
||||
if (Dialog?.Value != null)
|
||||
{
|
||||
yield return Dialog;
|
||||
yield return Dialog.Value;
|
||||
}
|
||||
|
||||
yield break;
|
||||
|
@ -67,30 +69,36 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
|
||||
protected override string OnComputeId()
|
||||
{
|
||||
return $"{this.GetType().Name}[{Dialog?.Id ?? this.dialogIdToCall}]";
|
||||
return $"{this.GetType().Name}[{Dialog?.ToString()}]";
|
||||
}
|
||||
|
||||
protected Dialog ResolveDialog(DialogContext dc)
|
||||
{
|
||||
if (this.Dialog != null)
|
||||
if (this.Dialog?.Value != null)
|
||||
{
|
||||
return this.Dialog;
|
||||
return this.Dialog.Value;
|
||||
}
|
||||
|
||||
var dialogId = this.dialogIdToCall ?? throw new Exception($"{this.GetType().Name} requires a dialog to be called.");
|
||||
return dc.FindDialog(dialogId) ?? throw new Exception($"{dialogId} not found.");
|
||||
var dcState = dc.GetState();
|
||||
|
||||
// NOTE: we call TryEvaluate instead of TryGetValue because we want the result of the expression as a string so we can
|
||||
// look up the string using external FindDialog().
|
||||
var (dialogId, _) = this.Dialog.Expression.TryEvaluate<string>(dcState);
|
||||
return dc.FindDialog(dialogId ?? throw new Exception($"{this.Dialog.ToString()} not found."));
|
||||
}
|
||||
|
||||
protected object BindOptions(DialogContext dc, object options)
|
||||
{
|
||||
var dcState = dc.GetState();
|
||||
|
||||
// binding options are static definition of options with overlay of passed in options);
|
||||
var bindingOptions = (JObject)ObjectPath.Merge(Options, options ?? new JObject());
|
||||
var bindingOptions = (JObject)ObjectPath.Merge(this.Options.GetValue(dcState), options ?? new JObject());
|
||||
var boundOptions = new JObject();
|
||||
|
||||
foreach (var binding in bindingOptions)
|
||||
{
|
||||
// evalute the value
|
||||
var (result, error) = new ExpressionEngine().Parse(binding.Value.ToString()).TryEvaluate(dc.GetState());
|
||||
var (value, error) = new ValueExpression(binding.Value).TryGetValue(dcState);
|
||||
|
||||
if (error != null)
|
||||
{
|
||||
|
@ -98,7 +106,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
}
|
||||
|
||||
// and store in options as the result
|
||||
boundOptions[binding.Key] = JToken.FromObject(result);
|
||||
ObjectPath.SetPathValue(boundOptions, binding.Key, value);
|
||||
}
|
||||
|
||||
return boundOptions;
|
||||
|
|
|
@ -19,10 +19,8 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
[JsonProperty("$kind")]
|
||||
public const string DeclarativeType = "Microsoft.BeginDialog";
|
||||
|
||||
private Expression disabled;
|
||||
|
||||
[JsonConstructor]
|
||||
public BeginDialog(string dialogIdToCall = null, IDictionary<string, string> options = null, [CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0)
|
||||
public BeginDialog(string dialogIdToCall = null, object options = null, [CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0)
|
||||
: base(dialogIdToCall, options)
|
||||
{
|
||||
this.RegisterSourceLocation(callerPath, callerLine);
|
||||
|
@ -38,11 +36,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
/// A boolean expression.
|
||||
/// </value>
|
||||
[JsonProperty("disabled")]
|
||||
public string Disabled
|
||||
{
|
||||
get { return disabled?.ToString(); }
|
||||
set { disabled = value != null ? new ExpressionEngine().Parse(value) : null; }
|
||||
}
|
||||
public BoolExpression Disabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the property path to store the dialog result in.
|
||||
|
@ -51,7 +45,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
/// The property path to store the dialog result in.
|
||||
/// </value>
|
||||
[JsonProperty("resultProperty")]
|
||||
public string ResultProperty { get; set; }
|
||||
public StringExpression ResultProperty { get; set; }
|
||||
|
||||
public override async Task<DialogTurnResult> BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
|
@ -60,7 +54,9 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
throw new ArgumentException($"{nameof(options)} cannot be a cancellation token");
|
||||
}
|
||||
|
||||
if (this.disabled != null && (bool?)this.disabled.TryEvaluate(dc.GetState()).value == true)
|
||||
var dcState = dc.GetState();
|
||||
|
||||
if (this.Disabled != null && this.Disabled.GetValue(dcState) == true)
|
||||
{
|
||||
return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
@ -71,7 +67,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
var boundOptions = BindOptions(dc, options);
|
||||
|
||||
// set the activity processed state (default is true)
|
||||
dc.GetState().SetValue(TurnPath.ACTIVITYPROCESSED, this.ActivityProcessed);
|
||||
dcState.SetValue(TurnPath.ACTIVITYPROCESSED, this.ActivityProcessed);
|
||||
|
||||
// start dialog with bound options passed in as the options
|
||||
return await dc.BeginDialogAsync(dialog.Id, options: boundOptions, cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
|
@ -79,9 +75,11 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
|
||||
public override async Task<DialogTurnResult> ResumeDialogAsync(DialogContext dc, DialogReason reason, object result = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
var dcState = dc.GetState();
|
||||
|
||||
if (this.ResultProperty != null)
|
||||
{
|
||||
dc.GetState().SetValue(this.ResultProperty, result);
|
||||
dcState.SetValue(this.ResultProperty.GetValue(dcState), result);
|
||||
}
|
||||
|
||||
// By default just end the current dialog and return result to parent.
|
||||
|
|
|
@ -18,8 +18,6 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
[JsonProperty("$kind")]
|
||||
public const string DeclarativeType = "Microsoft.BreakLoop";
|
||||
|
||||
private Expression disabled;
|
||||
|
||||
public BreakLoop([CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0)
|
||||
{
|
||||
this.RegisterSourceLocation(callerPath, callerLine);
|
||||
|
@ -35,11 +33,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
/// A boolean expression.
|
||||
/// </value>
|
||||
[JsonProperty("disabled")]
|
||||
public string Disabled
|
||||
{
|
||||
get { return disabled?.ToString(); }
|
||||
set { disabled = value != null ? new ExpressionEngine().Parse(value) : null; }
|
||||
}
|
||||
public BoolExpression Disabled { get; set; }
|
||||
|
||||
public override async Task<DialogTurnResult> BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
|
@ -48,7 +42,9 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
throw new ArgumentException($"{nameof(options)} cannot be a cancellation token");
|
||||
}
|
||||
|
||||
if (this.disabled != null && (bool?)this.disabled.TryEvaluate(dc.GetState()).value == true)
|
||||
var dcState = dc.GetState();
|
||||
|
||||
if (this.Disabled != null && this.Disabled.GetValue(dcState) == true)
|
||||
{
|
||||
return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
|
|
@ -18,8 +18,6 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
[JsonProperty("$kind")]
|
||||
public const string DeclarativeType = "Microsoft.CancelAllDialogs";
|
||||
|
||||
private Expression disabled;
|
||||
|
||||
[JsonConstructor]
|
||||
public CancelAllDialogs([CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0)
|
||||
: base()
|
||||
|
@ -37,11 +35,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
/// A boolean expression.
|
||||
/// </value>
|
||||
[JsonProperty("disabled")]
|
||||
public string Disabled
|
||||
{
|
||||
get { return disabled?.ToString(); }
|
||||
set { disabled = value != null ? new ExpressionEngine().Parse(value) : null; }
|
||||
}
|
||||
public BoolExpression Disabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets event name.
|
||||
|
@ -50,7 +44,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
/// Event name.
|
||||
/// </value>
|
||||
[JsonProperty("eventName")]
|
||||
public string EventName { get; set; }
|
||||
public StringExpression EventName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets value expression for EventValue.
|
||||
|
@ -59,7 +53,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
/// Value expression for EventValue.
|
||||
/// </value>
|
||||
[JsonProperty("eventValue")]
|
||||
public string EventValue { get; set; }
|
||||
public StringExpression EventValue { get; set; }
|
||||
|
||||
public override async Task<DialogTurnResult> BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
|
@ -68,24 +62,20 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
throw new ArgumentException($"{nameof(options)} cannot be a cancellation token");
|
||||
}
|
||||
|
||||
if (this.disabled != null && (bool?)this.disabled.TryEvaluate(dc.GetState()).value == true)
|
||||
var dcState = dc.GetState();
|
||||
|
||||
if (this.Disabled != null && this.Disabled.GetValue(dcState) == true)
|
||||
{
|
||||
return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
object eventValue = null;
|
||||
if (this.EventValue != null)
|
||||
{
|
||||
eventValue = new ExpressionEngine().Parse(this.EventValue).TryEvaluate(dc.GetState());
|
||||
}
|
||||
|
||||
if (dc.Parent == null)
|
||||
{
|
||||
return await dc.CancelAllDialogsAsync(true, EventName, eventValue, cancellationToken).ConfigureAwait(false);
|
||||
return await dc.CancelAllDialogsAsync(true, EventName.GetValue(dcState), this.EventValue.GetValue(dcState), cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
var turnResult = await dc.Parent.CancelAllDialogsAsync(true, EventName, eventValue, cancellationToken).ConfigureAwait(false);
|
||||
var turnResult = await dc.Parent.CancelAllDialogsAsync(true, EventName.GetValue(dcState), this.EventValue.GetValue(dcState), cancellationToken).ConfigureAwait(false);
|
||||
turnResult.ParentEnded = true;
|
||||
return turnResult;
|
||||
}
|
||||
|
|
|
@ -15,7 +15,6 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
public class CodeAction : Dialog
|
||||
{
|
||||
private readonly CodeActionHandler codeHandler;
|
||||
private Expression disabled;
|
||||
|
||||
public CodeAction(CodeActionHandler codeHandler, [CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0)
|
||||
: base()
|
||||
|
@ -34,11 +33,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
/// A boolean expression.
|
||||
/// </value>
|
||||
[JsonProperty("disabled")]
|
||||
public string Disabled
|
||||
{
|
||||
get { return disabled?.ToString(); }
|
||||
set { disabled = value != null ? new ExpressionEngine().Parse(value) : null; }
|
||||
}
|
||||
public BoolExpression Disabled { get; set; }
|
||||
|
||||
public override async Task<DialogTurnResult> BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
|
@ -47,7 +42,9 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
throw new ArgumentException($"{nameof(options)} cannot be a cancellation token");
|
||||
}
|
||||
|
||||
if (this.disabled != null && (bool?)this.disabled.TryEvaluate(dc.GetState()).value == true)
|
||||
var dcState = dc.GetState();
|
||||
|
||||
if (this.Disabled != null && this.Disabled.GetValue(dcState) == true)
|
||||
{
|
||||
return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
|
|
@ -18,8 +18,6 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
[JsonProperty("$kind")]
|
||||
public const string DeclarativeType = "Microsoft.ContinueLoop";
|
||||
|
||||
private Expression disabled;
|
||||
|
||||
public ContinueLoop([CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0)
|
||||
{
|
||||
this.RegisterSourceLocation(callerPath, callerLine);
|
||||
|
@ -35,11 +33,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
/// A boolean expression.
|
||||
/// </value>
|
||||
[JsonProperty("disabled")]
|
||||
public string Disabled
|
||||
{
|
||||
get { return disabled?.ToString(); }
|
||||
set { disabled = value != null ? new ExpressionEngine().Parse(value) : null; }
|
||||
}
|
||||
public BoolExpression Disabled { get; set; }
|
||||
|
||||
public override async Task<DialogTurnResult> BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
|
@ -48,7 +42,9 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
throw new ArgumentException($"{nameof(options)} cannot be a cancellation token");
|
||||
}
|
||||
|
||||
if (this.disabled != null && (bool?)this.disabled.TryEvaluate(dc.GetState()).value == true)
|
||||
var dcState = dc.GetState();
|
||||
|
||||
if (this.Disabled != null && this.Disabled.GetValue(dcState) == true)
|
||||
{
|
||||
return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
|
|
@ -18,8 +18,6 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
[JsonProperty("$kind")]
|
||||
public const string DeclarativeType = "Microsoft.DebugBreak";
|
||||
|
||||
private Expression disabled;
|
||||
|
||||
public DebugBreak([CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0)
|
||||
{
|
||||
this.RegisterSourceLocation(callerPath, callerLine);
|
||||
|
@ -35,11 +33,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
/// A boolean expression.
|
||||
/// </value>
|
||||
[JsonProperty("disabled")]
|
||||
public string Disabled
|
||||
{
|
||||
get { return disabled?.ToString(); }
|
||||
set { disabled = value != null ? new ExpressionEngine().Parse(value) : null; }
|
||||
}
|
||||
public BoolExpression Disabled { get; set; }
|
||||
|
||||
public override async Task<DialogTurnResult> BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
|
@ -48,7 +42,9 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
throw new ArgumentException($"{nameof(options)} cannot be a cancellation token");
|
||||
}
|
||||
|
||||
if (this.disabled != null && (bool?)this.disabled.TryEvaluate(dc.GetState()).value == true)
|
||||
var dcState = dc.GetState();
|
||||
|
||||
if (this.Disabled != null && this.Disabled.GetValue(dcState) == true)
|
||||
{
|
||||
return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
|
|
@ -20,9 +20,6 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
[JsonProperty("$kind")]
|
||||
public const string DeclarativeType = "Microsoft.DeleteActivity";
|
||||
|
||||
private Expression activityId;
|
||||
private Expression disabled;
|
||||
|
||||
[JsonConstructor]
|
||||
public DeleteActivity([CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0)
|
||||
{
|
||||
|
@ -39,22 +36,14 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
/// A boolean expression.
|
||||
/// </value>
|
||||
[JsonProperty("disabled")]
|
||||
public string Disabled
|
||||
{
|
||||
get { return disabled?.ToString(); }
|
||||
set { disabled = value != null ? new ExpressionEngine().Parse(value) : null; }
|
||||
}
|
||||
public BoolExpression Disabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the expression which resolves to the activityId to update.
|
||||
/// </summary>
|
||||
/// <value>Expression to activityId.</value>
|
||||
[JsonProperty("activityId")]
|
||||
public string ActivityId
|
||||
{
|
||||
get { return activityId.ToString(); }
|
||||
set { activityId = new ExpressionEngine().Parse(value); }
|
||||
}
|
||||
public StringExpression ActivityId { get; set; }
|
||||
|
||||
public override async Task<DialogTurnResult> BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
|
@ -63,12 +52,14 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
throw new ArgumentException($"{nameof(options)} cannot be a cancellation token");
|
||||
}
|
||||
|
||||
if (this.disabled != null && (bool?)this.disabled.TryEvaluate(dc.GetState()).value == true)
|
||||
var dcState = dc.GetState();
|
||||
|
||||
if (this.Disabled != null && this.Disabled.GetValue(dcState) == true)
|
||||
{
|
||||
return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
var (result, error) = new ExpressionEngine().Parse(this.ActivityId).TryEvaluate(dc.GetState());
|
||||
var (result, error) = this.ActivityId.TryGetValue(dcState);
|
||||
if (error != null)
|
||||
{
|
||||
throw new ArgumentException(error);
|
||||
|
|
|
@ -20,8 +20,6 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
[JsonProperty("$kind")]
|
||||
public const string DeclarativeType = "Microsoft.DeleteProperties";
|
||||
|
||||
private Expression disabled;
|
||||
|
||||
[JsonConstructor]
|
||||
public DeleteProperties([CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0)
|
||||
: base()
|
||||
|
@ -39,11 +37,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
/// A boolean expression.
|
||||
/// </value>
|
||||
[JsonProperty("disabled")]
|
||||
public string Disabled
|
||||
{
|
||||
get { return disabled?.ToString(); }
|
||||
set { disabled = value != null ? new ExpressionEngine().Parse(value) : null; }
|
||||
}
|
||||
public BoolExpression Disabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets properties to remove.
|
||||
|
@ -55,7 +49,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
/// Collection of property paths to remove.
|
||||
/// </value>
|
||||
[JsonProperty("properties")]
|
||||
public List<string> Properties { get; set; } = new List<string>();
|
||||
public List<StringExpression> Properties { get; set; } = new List<StringExpression>();
|
||||
|
||||
public override async Task<DialogTurnResult> BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
|
@ -64,7 +58,9 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
throw new ArgumentException($"{nameof(options)} cannot be a cancellation token");
|
||||
}
|
||||
|
||||
if (this.disabled != null && (bool?)this.disabled.TryEvaluate(dc.GetState()).value == true)
|
||||
var dcState = dc.GetState();
|
||||
|
||||
if (this.Disabled != null && this.Disabled.GetValue(dcState) == true)
|
||||
{
|
||||
return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
@ -76,7 +72,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
{
|
||||
foreach (var property in this.Properties)
|
||||
{
|
||||
dc.GetState().RemoveValue(property);
|
||||
dcState.RemoveValue(property.GetValue(dcState));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -18,8 +18,6 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
[JsonProperty("$kind")]
|
||||
public const string DeclarativeType = "Microsoft.DeleteProperty";
|
||||
|
||||
private Expression disabled;
|
||||
|
||||
[JsonConstructor]
|
||||
public DeleteProperty([CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0)
|
||||
: base()
|
||||
|
@ -47,11 +45,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
/// A boolean expression.
|
||||
/// </value>
|
||||
[JsonProperty("disabled")]
|
||||
public string Disabled
|
||||
{
|
||||
get { return disabled?.ToString(); }
|
||||
set { disabled = value != null ? new ExpressionEngine().Parse(value) : null; }
|
||||
}
|
||||
public BoolExpression Disabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets property path to remove.
|
||||
|
@ -63,7 +57,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
/// Property path to remove.
|
||||
/// </value>
|
||||
[JsonProperty("property")]
|
||||
public string Property { get; set; }
|
||||
public StringExpression Property { get; set; }
|
||||
|
||||
public override async Task<DialogTurnResult> BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
|
@ -72,7 +66,9 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
throw new ArgumentException($"{nameof(options)} cannot be a cancellation token");
|
||||
}
|
||||
|
||||
if (this.disabled != null && (bool?)this.disabled.TryEvaluate(dc.GetState()).value == true)
|
||||
var dcState = dc.GetState();
|
||||
|
||||
if (this.Disabled != null && this.Disabled.GetValue(dcState) == true)
|
||||
{
|
||||
return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
@ -80,7 +76,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
// Ensure planning context
|
||||
if (dc is SequenceContext planning)
|
||||
{
|
||||
dc.GetState().RemoveValue(Property);
|
||||
dcState.RemoveValue(Property.GetValue(dcState));
|
||||
return await dc.EndDialogAsync();
|
||||
}
|
||||
else
|
||||
|
|
|
@ -20,8 +20,6 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
[JsonProperty("$kind")]
|
||||
public const string DeclarativeType = "Microsoft.EditActions";
|
||||
|
||||
private Expression disabled;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="EditActions"/> class.
|
||||
/// </summary>
|
||||
|
@ -44,11 +42,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
/// A boolean expression.
|
||||
/// </value>
|
||||
[JsonProperty("disabled")]
|
||||
public string Disabled
|
||||
{
|
||||
get { return disabled?.ToString(); }
|
||||
set { disabled = value != null ? new ExpressionEngine().Parse(value) : null; }
|
||||
}
|
||||
public BoolExpression Disabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the actions to be applied to the active action.
|
||||
|
@ -66,7 +60,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
/// The type of change to appy to the active actions.
|
||||
/// </value>
|
||||
[JsonProperty("changeType")]
|
||||
public ActionChangeType ChangeType { get; set; }
|
||||
public EnumExpression<ActionChangeType> ChangeType { get; set; } = new EnumExpression<ActionChangeType>();
|
||||
|
||||
public virtual IEnumerable<Dialog> GetDependencies()
|
||||
{
|
||||
|
@ -75,7 +69,9 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
|
||||
public override async Task<DialogTurnResult> BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
if (this.disabled != null && (bool?)this.disabled.TryEvaluate(dc.GetState()).value == true)
|
||||
var dcState = dc.GetState();
|
||||
|
||||
if (this.Disabled != null && this.Disabled.GetValue(dcState) == true)
|
||||
{
|
||||
return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
@ -91,7 +87,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
|
||||
var changes = new ActionChangeList()
|
||||
{
|
||||
ChangeType = ChangeType,
|
||||
ChangeType = ChangeType.GetValue(dcState),
|
||||
Actions = planActions.ToList()
|
||||
};
|
||||
|
||||
|
|
|
@ -22,11 +22,6 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
[JsonProperty("$kind")]
|
||||
public const string DeclarativeType = "Microsoft.EditArray";
|
||||
|
||||
private Expression value;
|
||||
private Expression itemsProperty;
|
||||
private Expression resultProperty;
|
||||
private Expression disabled;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="EditArray"/> class.
|
||||
/// </summary>
|
||||
|
@ -34,10 +29,10 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
/// <param name="arrayProperty">array property (optional).</param>
|
||||
/// <param name="value">value to insert.</param>
|
||||
/// <param name="resultProperty">output property to put Pop/Take into.</param>
|
||||
public EditArray(ArrayChangeType changeType, string arrayProperty = null, string value = null, string resultProperty = null)
|
||||
public EditArray(ArrayChangeType changeType, string arrayProperty = null, object value = null, string resultProperty = null)
|
||||
: base()
|
||||
{
|
||||
this.ChangeType = changeType;
|
||||
this.ChangeType = new EnumExpression<ArrayChangeType>(changeType);
|
||||
|
||||
if (!string.IsNullOrEmpty(arrayProperty))
|
||||
{
|
||||
|
@ -49,11 +44,19 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
case ArrayChangeType.Clear:
|
||||
case ArrayChangeType.Pop:
|
||||
case ArrayChangeType.Take:
|
||||
if (ResultProperty != null)
|
||||
{
|
||||
this.ResultProperty = resultProperty;
|
||||
}
|
||||
|
||||
break;
|
||||
case ArrayChangeType.Push:
|
||||
case ArrayChangeType.Remove:
|
||||
this.Value = value;
|
||||
if (value != null)
|
||||
{
|
||||
this.Value = new ValueExpression(value);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -101,7 +104,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
/// Type of change being applied.
|
||||
/// </value>
|
||||
[JsonProperty("changeType")]
|
||||
public ArrayChangeType ChangeType { get; set; }
|
||||
public EnumExpression<ArrayChangeType> ChangeType { get; set; } = new EnumExpression<ArrayChangeType>(default(ArrayChangeType));
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets an optional expression which if is true will disable this action.
|
||||
|
@ -113,11 +116,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
/// A boolean expression.
|
||||
/// </value>
|
||||
[JsonProperty("disabled")]
|
||||
public string Disabled
|
||||
{
|
||||
get { return disabled?.ToString(); }
|
||||
set { disabled = value != null ? new ExpressionEngine().Parse(value) : null; }
|
||||
}
|
||||
public BoolExpression Disabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets property path expression to the collection of items.
|
||||
|
@ -126,11 +125,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
/// Property path expression to the collection of items.
|
||||
/// </value>
|
||||
[JsonProperty("itemsProperty")]
|
||||
public string ItemsProperty
|
||||
{
|
||||
get { return itemsProperty?.ToString(); }
|
||||
set { this.itemsProperty = (value != null) ? new ExpressionEngine().Parse(value) : null; }
|
||||
}
|
||||
public StringExpression ItemsProperty { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the path expression to store the result of the action.
|
||||
|
@ -139,11 +134,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
/// The path expression to store the result of the action.
|
||||
/// </value>
|
||||
[JsonProperty("resultProperty")]
|
||||
public string ResultProperty
|
||||
{
|
||||
get { return resultProperty?.ToString(); }
|
||||
set { this.resultProperty = (value != null) ? new ExpressionEngine().Parse(value) : null; }
|
||||
}
|
||||
public StringExpression ResultProperty { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the expression of the value to put onto the array.
|
||||
|
@ -152,11 +143,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
/// The expression of the value to put onto the array.
|
||||
/// </value>
|
||||
[JsonProperty("value")]
|
||||
public string Value
|
||||
{
|
||||
get { return value?.ToString(); }
|
||||
set { this.value = (value != null) ? new ExpressionEngine().Parse(value) : null; }
|
||||
}
|
||||
public ValueExpression Value { get; set; } = new ValueExpression();
|
||||
|
||||
public override async Task<DialogTurnResult> BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
|
@ -165,22 +152,24 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
throw new ArgumentException($"{nameof(options)} cannot be a cancellation token");
|
||||
}
|
||||
|
||||
if (this.disabled != null && (bool?)this.disabled.TryEvaluate(dc.GetState()).value == true)
|
||||
var dcState = dc.GetState();
|
||||
|
||||
if (this.Disabled != null && this.Disabled.GetValue(dcState))
|
||||
{
|
||||
return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(ItemsProperty))
|
||||
if (ItemsProperty == null)
|
||||
{
|
||||
throw new Exception($"EditArray: \"{ChangeType}\" operation couldn't be performed because the arrayProperty wasn't specified.");
|
||||
}
|
||||
|
||||
var array = dc.GetState().GetValue<JArray>(this.ItemsProperty, () => new JArray());
|
||||
var array = dcState.GetValue<JArray>(this.ItemsProperty.GetValue(dcState), () => new JArray());
|
||||
|
||||
object item = null;
|
||||
object result = null;
|
||||
|
||||
switch (ChangeType)
|
||||
switch (ChangeType.GetValue(dcState))
|
||||
{
|
||||
case ArrayChangeType.Pop:
|
||||
item = array[array.Count - 1];
|
||||
|
@ -189,7 +178,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
break;
|
||||
case ArrayChangeType.Push:
|
||||
EnsureValue();
|
||||
var (itemResult, error) = this.value.TryEvaluate(dc.GetState());
|
||||
var (itemResult, error) = this.Value.TryGetValue(dcState);
|
||||
if (error == null && itemResult != null)
|
||||
{
|
||||
array.Add(itemResult);
|
||||
|
@ -208,7 +197,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
break;
|
||||
case ArrayChangeType.Remove:
|
||||
EnsureValue();
|
||||
(itemResult, error) = this.value.TryEvaluate(dc.GetState());
|
||||
(itemResult, error) = this.Value.TryGetValue(dcState);
|
||||
if (error == null && itemResult != null)
|
||||
{
|
||||
result = false;
|
||||
|
@ -230,11 +219,11 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
break;
|
||||
}
|
||||
|
||||
dc.GetState().SetValue(this.ItemsProperty, array);
|
||||
dcState.SetValue(this.ItemsProperty.GetValue(dcState), array);
|
||||
|
||||
if (ResultProperty != null)
|
||||
{
|
||||
dc.GetState().SetValue(this.ResultProperty, result);
|
||||
dcState.SetValue(this.ResultProperty.GetValue(dcState), result);
|
||||
}
|
||||
|
||||
return await dc.EndDialogAsync(result);
|
||||
|
|
|
@ -18,17 +18,23 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
[JsonProperty("$kind")]
|
||||
public const string DeclarativeType = "Microsoft.EmitEvent";
|
||||
|
||||
private Expression eventValue;
|
||||
private Expression disabled;
|
||||
|
||||
[JsonConstructor]
|
||||
public EmitEvent(string eventName = null, string eventValue = null, bool bubble = false, [CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0)
|
||||
public EmitEvent(string eventName = null, object eventValue = null, bool bubble = false, [CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0)
|
||||
: base()
|
||||
{
|
||||
this.RegisterSourceLocation(callerPath, callerLine);
|
||||
|
||||
if (eventName != null)
|
||||
{
|
||||
this.EventName = eventName;
|
||||
this.EventValue = eventValue;
|
||||
this.BubbleEvent = bubble;
|
||||
}
|
||||
|
||||
if (eventValue != null)
|
||||
{
|
||||
this.EventValue = new ValueExpression(eventValue);
|
||||
}
|
||||
|
||||
this.BubbleEvent = new BoolExpression(bubble);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -41,11 +47,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
/// A boolean expression.
|
||||
/// </value>
|
||||
[JsonProperty("disabled")]
|
||||
public string Disabled
|
||||
{
|
||||
get { return disabled?.ToString(); }
|
||||
set { disabled = value != null ? new ExpressionEngine().Parse(value) : null; }
|
||||
}
|
||||
public BoolExpression Disabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the name of the event to emit.
|
||||
|
@ -54,7 +56,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
/// The name of the event to emit.
|
||||
/// </value>
|
||||
[JsonProperty("eventName")]
|
||||
public string EventName { get; set; }
|
||||
public StringExpression EventName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the memory property path to use to get the value to send as part of the event.
|
||||
|
@ -63,11 +65,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
/// The memory property path to use to get the value to send as part of the event.
|
||||
/// </value>
|
||||
[JsonProperty("eventValue")]
|
||||
public string EventValue
|
||||
{
|
||||
get { return eventValue?.ToString(); }
|
||||
set { this.eventValue = (value != null) ? new ExpressionEngine().Parse(value) : null; }
|
||||
}
|
||||
public ValueExpression EventValue { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether the event should bubble to parents or not.
|
||||
|
@ -76,7 +74,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
/// A value indicating whether gets or sets whether the event should bubble to parents or not.
|
||||
/// </value>
|
||||
[JsonProperty("bubbleEvent")]
|
||||
public bool BubbleEvent { get; set; }
|
||||
public BoolExpression BubbleEvent { get; set; }
|
||||
|
||||
public override async Task<DialogTurnResult> BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
|
@ -85,27 +83,31 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
throw new ArgumentException($"{nameof(options)} cannot be a cancellation token");
|
||||
}
|
||||
|
||||
if (this.disabled != null && (bool?)this.disabled.TryEvaluate(dc.GetState()).value == true)
|
||||
var dcState = dc.GetState();
|
||||
|
||||
if (this.Disabled != null && this.Disabled.GetValue(dcState) == true)
|
||||
{
|
||||
return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
var handled = false;
|
||||
if (eventValue != null)
|
||||
bool handled;
|
||||
var eventName = EventName?.GetValue(dcState);
|
||||
var bubbleEvent = BubbleEvent.GetValue(dcState);
|
||||
if (EventValue != null)
|
||||
{
|
||||
var (value, valueError) = this.eventValue.TryEvaluate(dc.GetState());
|
||||
var (value, valueError) = this.EventValue.TryGetValue(dcState);
|
||||
if (valueError == null)
|
||||
{
|
||||
handled = await dc.EmitEventAsync(EventName, value, BubbleEvent, false, cancellationToken).ConfigureAwait(false);
|
||||
handled = await dc.EmitEventAsync(eventName, value, bubbleEvent, false, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception($"Expression evaluation resulted in an error. Expression: {eventValue.ToString()}. Error: {valueError}");
|
||||
throw new Exception($"Expression evaluation resulted in an error. Expression: {EventValue.ToString()}. Error: {valueError}");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
handled = await dc.EmitEventAsync(EventName, EventValue, BubbleEvent, false, cancellationToken).ConfigureAwait(false);
|
||||
handled = await dc.EmitEventAsync(eventName, EventValue, bubbleEvent, false, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
return await dc.EndDialogAsync(handled, cancellationToken).ConfigureAwait(false);
|
||||
|
@ -113,7 +115,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
|
||||
protected override string OnComputeId()
|
||||
{
|
||||
return $"{this.GetType().Name}[{EventName ?? string.Empty}]";
|
||||
return $"{this.GetType().Name}[{EventName.ToString() ?? string.Empty}]";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,18 +18,15 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
[JsonProperty("$kind")]
|
||||
public const string DeclarativeType = "Microsoft.EndDialog";
|
||||
|
||||
private Expression value;
|
||||
private Expression disabled;
|
||||
|
||||
[JsonConstructor]
|
||||
public EndDialog(string value = null, [CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0)
|
||||
public EndDialog(object value = null, [CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0)
|
||||
: base()
|
||||
{
|
||||
this.RegisterSourceLocation(callerPath, callerLine);
|
||||
|
||||
if (!string.IsNullOrEmpty(value))
|
||||
if (value != null)
|
||||
{
|
||||
this.Value = value;
|
||||
this.Value = new ValueExpression(value);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -43,11 +40,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
/// A boolean expression.
|
||||
/// </value>
|
||||
[JsonProperty("disabled")]
|
||||
public string Disabled
|
||||
{
|
||||
get { return disabled?.ToString(); }
|
||||
set { disabled = value != null ? new ExpressionEngine().Parse(value) : null; }
|
||||
}
|
||||
public BoolExpression Disabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value expression for the result to be returned to the caller.
|
||||
|
@ -56,11 +49,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
/// A value expression for the result to be returned to the caller.
|
||||
/// </value>
|
||||
[JsonProperty("value")]
|
||||
public string Value
|
||||
{
|
||||
get { return value?.ToString(); }
|
||||
set { this.value = (value != null) ? new ExpressionEngine().Parse(value) : null; }
|
||||
}
|
||||
public ValueExpression Value { get; set; }
|
||||
|
||||
public override async Task<DialogTurnResult> BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
|
@ -69,14 +58,16 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
throw new ArgumentException($"{nameof(options)} cannot be a cancellation token");
|
||||
}
|
||||
|
||||
if (this.disabled != null && (bool?)this.disabled.TryEvaluate(dc.GetState()).value == true)
|
||||
var dcState = dc.GetState();
|
||||
|
||||
if (this.Disabled != null && this.Disabled.GetValue(dcState) == true)
|
||||
{
|
||||
return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
if (this.Value != null)
|
||||
{
|
||||
var (result, error) = this.value.TryEvaluate(dc.GetState());
|
||||
var (result, error) = this.Value.TryGetValue(dcState);
|
||||
return await EndParentDialogAsync(dc, result, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
|
@ -104,7 +95,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
|
||||
protected override string OnComputeId()
|
||||
{
|
||||
return $"{this.GetType().Name}({this.Value ?? string.Empty})";
|
||||
return $"{this.GetType().Name}({this.Value?.ToString() ?? string.Empty})";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,8 +18,6 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
[JsonProperty("$kind")]
|
||||
public const string DeclarativeType = "Microsoft.EndTurn";
|
||||
|
||||
private Expression disabled;
|
||||
|
||||
[JsonConstructor]
|
||||
public EndTurn([CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0)
|
||||
: base()
|
||||
|
@ -38,11 +36,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
/// A boolean expression.
|
||||
/// </value>
|
||||
[JsonProperty("disabled")]
|
||||
public string Disabled
|
||||
{
|
||||
get { return disabled?.ToString(); }
|
||||
set { disabled = value != null ? new ExpressionEngine().Parse(value) : null; }
|
||||
}
|
||||
public BoolExpression Disabled { get; set; }
|
||||
|
||||
public override Task<DialogTurnResult> BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
|
@ -51,7 +45,9 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
throw new ArgumentException($"{nameof(options)} cannot be a cancellation token");
|
||||
}
|
||||
|
||||
if (this.disabled != null && (bool?)this.disabled.TryEvaluate(dc.GetState()).value == true)
|
||||
var dcState = dc.GetState();
|
||||
|
||||
if (this.Disabled != null && this.Disabled.GetValue(dcState) == true)
|
||||
{
|
||||
return dc.EndDialogAsync(cancellationToken: cancellationToken);
|
||||
}
|
||||
|
|
|
@ -23,8 +23,6 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
private const string INDEX = "dialog.foreach.index";
|
||||
private const string VALUE = "dialog.foreach.value";
|
||||
|
||||
private Expression disabled;
|
||||
|
||||
[JsonConstructor]
|
||||
public Foreach([CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0)
|
||||
: base()
|
||||
|
@ -42,11 +40,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
/// A boolean expression.
|
||||
/// </value>
|
||||
[JsonProperty("disabled")]
|
||||
public string Disabled
|
||||
{
|
||||
get { return disabled?.ToString(); }
|
||||
set { disabled = value != null ? new ExpressionEngine().Parse(value) : null; }
|
||||
}
|
||||
public BoolExpression Disabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets property path expression to the collection of items.
|
||||
|
@ -55,7 +49,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
/// Property path expression to the collection of items.
|
||||
/// </value>
|
||||
[JsonProperty("itemsProperty")]
|
||||
public string ItemsProperty { get; set; }
|
||||
public StringExpression ItemsProperty { get; set; }
|
||||
|
||||
public override async Task<DialogTurnResult> BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
|
@ -64,12 +58,14 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
throw new ArgumentException($"{nameof(options)} cannot be a cancellation token");
|
||||
}
|
||||
|
||||
if (this.disabled != null && (bool?)this.disabled.TryEvaluate(dc.GetState()).value == true)
|
||||
var dcState = dc.GetState();
|
||||
|
||||
if (this.Disabled != null && this.Disabled.GetValue(dcState) == true)
|
||||
{
|
||||
return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
dc.GetState().SetValue(INDEX, -1);
|
||||
dcState.SetValue(INDEX, -1);
|
||||
return await this.NextItemAsync(dc, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
|
@ -91,17 +87,16 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
protected virtual async Task<DialogTurnResult> NextItemAsync(DialogContext dc, CancellationToken cancellationToken = default)
|
||||
{
|
||||
// Get list information
|
||||
var itemsProperty = new ExpressionEngine().Parse(this.ItemsProperty);
|
||||
var (itemList, error) = itemsProperty.TryEvaluate(dc.GetState());
|
||||
var list = JArray.FromObject(itemList);
|
||||
var index = dc.GetState().GetIntValue(INDEX);
|
||||
var dcState = dc.GetState();
|
||||
var list = dcState.GetValue<JArray>(this.ItemsProperty.GetValue(dcState));
|
||||
var index = dcState.GetIntValue(INDEX);
|
||||
|
||||
// Next item
|
||||
if (++index < list.Count)
|
||||
{
|
||||
// Persist index and value
|
||||
dc.GetState().SetValue(VALUE, list[index]);
|
||||
dc.GetState().SetValue(INDEX, index);
|
||||
dcState.SetValue(VALUE, list[index]);
|
||||
dcState.SetValue(INDEX, index);
|
||||
|
||||
// Start loop
|
||||
return await this.BeginActionAsync(dc, 0, cancellationToken).ConfigureAwait(false);
|
||||
|
|
|
@ -25,8 +25,6 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
private const string FOREACHPAGE = "dialog.foreach.page";
|
||||
private const string FOREACHPAGEINDEX = "dialog.foreach.pageindex";
|
||||
|
||||
private Expression disabled;
|
||||
|
||||
[JsonConstructor]
|
||||
public ForeachPage([CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0)
|
||||
: base()
|
||||
|
@ -44,18 +42,14 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
/// A boolean expression.
|
||||
/// </value>
|
||||
[JsonProperty("disabled")]
|
||||
public string Disabled
|
||||
{
|
||||
get { return disabled?.ToString(); }
|
||||
set { disabled = value != null ? new ExpressionEngine().Parse(value) : null; }
|
||||
}
|
||||
public BoolExpression Disabled { get; set; }
|
||||
|
||||
// Expression used to compute the list that should be enumerated.
|
||||
[JsonProperty("itemsProperty")]
|
||||
public string ItemsProperty { get; set; }
|
||||
public StringExpression ItemsProperty { get; set; }
|
||||
|
||||
[JsonProperty("pageSize")]
|
||||
public int PageSize { get; set; } = 10;
|
||||
public IntExpression PageSize { get; set; } = 10;
|
||||
|
||||
public override async Task<DialogTurnResult> BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
|
@ -64,7 +58,9 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
throw new ArgumentException($"{nameof(options)} cannot be a cancellation token");
|
||||
}
|
||||
|
||||
if (this.disabled != null && (bool?)this.disabled.TryEvaluate(dc.GetState()).value == true)
|
||||
var dcState = dc.GetState();
|
||||
|
||||
if (this.Disabled != null && this.Disabled.GetValue(dcState) == true)
|
||||
{
|
||||
return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
@ -94,20 +90,20 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
|
||||
private async Task<DialogTurnResult> NextPageAsync(DialogContext dc, CancellationToken cancellationToken)
|
||||
{
|
||||
Expression itemsProperty = new ExpressionEngine().Parse(this.ItemsProperty);
|
||||
int pageIndex = dc.GetState().GetIntValue(FOREACHPAGEINDEX, 0);
|
||||
int pageSize = this.PageSize;
|
||||
var dcState = dc.GetState();
|
||||
int pageIndex = dcState.GetIntValue(FOREACHPAGEINDEX, 0);
|
||||
int pageSize = this.PageSize.GetValue(dcState);
|
||||
int itemOffset = pageSize * pageIndex;
|
||||
|
||||
var (items, error) = itemsProperty.TryEvaluate(dc.GetState());
|
||||
if (error == null)
|
||||
var itemsProperty = this.ItemsProperty.GetValue(dcState);
|
||||
if (dcState.TryGetValue<object>(itemsProperty, out object items))
|
||||
{
|
||||
var page = this.GetPage(items, itemOffset, pageSize);
|
||||
|
||||
if (page.Any())
|
||||
{
|
||||
dc.GetState().SetValue(FOREACHPAGE, page);
|
||||
dc.GetState().SetValue(FOREACHPAGEINDEX, ++pageIndex);
|
||||
dcState.SetValue(FOREACHPAGE, page);
|
||||
dcState.SetValue(FOREACHPAGEINDEX, ++pageIndex);
|
||||
return await this.BeginActionAsync(dc, 0, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,9 +18,6 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
[JsonProperty("$kind")]
|
||||
public const string DeclarativeType = "Microsoft.GetActivityMembers";
|
||||
|
||||
private Expression activityId;
|
||||
private Expression disabled;
|
||||
|
||||
[JsonConstructor]
|
||||
public GetActivityMembers([CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0)
|
||||
: base()
|
||||
|
@ -38,11 +35,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
/// A boolean expression.
|
||||
/// </value>
|
||||
[JsonProperty("disabled")]
|
||||
public string Disabled
|
||||
{
|
||||
get { return disabled?.ToString(); }
|
||||
set { disabled = value != null ? new ExpressionEngine().Parse(value) : null; }
|
||||
}
|
||||
public BoolExpression Disabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets property path to put the value in.
|
||||
|
@ -51,7 +44,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
/// Property path to put the value in.
|
||||
/// </value>
|
||||
[JsonProperty("property")]
|
||||
public string Property { get; set; }
|
||||
public StringExpression Property { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the expression to get the value to put into property path.
|
||||
|
@ -60,11 +53,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
/// The expression to get the value to put into property path. If this is missing, then the current turn Activity.id will be used.
|
||||
/// </value>
|
||||
[JsonProperty("activityId")]
|
||||
public string ActivityId
|
||||
{
|
||||
get { return activityId?.ToString(); }
|
||||
set { this.activityId = (value != null) ? new ExpressionEngine().Parse(value) : null; }
|
||||
}
|
||||
public StringExpression ActivityId { get; set; }
|
||||
|
||||
public override async Task<DialogTurnResult> BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
|
@ -73,7 +62,9 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
throw new ArgumentException($"{nameof(options)} cannot be a cancellation token");
|
||||
}
|
||||
|
||||
if (this.disabled != null && (bool?)this.disabled.TryEvaluate(dc.GetState()).value == true)
|
||||
var dcState = dc.GetState();
|
||||
|
||||
if (this.Disabled != null && this.Disabled.GetValue(dcState) == true)
|
||||
{
|
||||
return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
@ -85,9 +76,9 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
}
|
||||
|
||||
string id = dc.Context.Activity.Id;
|
||||
if (this.activityId != null)
|
||||
if (this.ActivityId != null)
|
||||
{
|
||||
var (value, valueError) = this.activityId.TryEvaluate(dc.GetState());
|
||||
var (value, valueError) = this.ActivityId.TryGetValue(dcState);
|
||||
if (valueError != null)
|
||||
{
|
||||
throw new Exception($"Expression evaluation resulted in an error. Expression: {this.ActivityId}. Error: {valueError}");
|
||||
|
@ -98,14 +89,14 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
|
||||
var result = await bfAdapter.GetActivityMembersAsync(dc.Context, id, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
dc.GetState().SetValue(this.Property, result);
|
||||
dcState.SetValue(this.Property.GetValue(dcState), result);
|
||||
|
||||
return await dc.EndDialogAsync(result, cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
protected override string OnComputeId()
|
||||
{
|
||||
return $"{this.GetType().Name}[{this.ActivityId ?? string.Empty},{this.Property ?? string.Empty}]";
|
||||
return $"{this.GetType().Name}[{this.ActivityId?.ToString() ?? string.Empty},{this.Property ?? string.Empty}]";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,8 +18,6 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
[JsonProperty("$kind")]
|
||||
public const string DeclarativeType = "Microsoft.GetConversationMembers";
|
||||
|
||||
private Expression disabled;
|
||||
|
||||
[JsonConstructor]
|
||||
public GetConversationMembers([CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0)
|
||||
: base()
|
||||
|
@ -37,11 +35,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
/// A boolean expression.
|
||||
/// </value>
|
||||
[JsonProperty("disabled")]
|
||||
public string Disabled
|
||||
{
|
||||
get { return disabled?.ToString(); }
|
||||
set { disabled = value != null ? new ExpressionEngine().Parse(value) : null; }
|
||||
}
|
||||
public BoolExpression Disabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets property path to put the value in.
|
||||
|
@ -50,7 +44,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
/// Property path to put the value in.
|
||||
/// </value>
|
||||
[JsonProperty("property")]
|
||||
public string Property { get; set; }
|
||||
public StringExpression Property { get; set; }
|
||||
|
||||
public override async Task<DialogTurnResult> BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
|
@ -59,7 +53,9 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
throw new ArgumentException($"{nameof(options)} cannot be a cancellation token");
|
||||
}
|
||||
|
||||
if (this.disabled != null && (bool?)this.disabled.TryEvaluate(dc.GetState()).value == true)
|
||||
var dcState = dc.GetState();
|
||||
|
||||
if (this.Disabled != null && this.Disabled.GetValue(dcState) == true)
|
||||
{
|
||||
return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
@ -74,7 +70,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
|
||||
if (this.Property != null)
|
||||
{
|
||||
dc.GetState().SetValue(this.Property, result);
|
||||
dcState.SetValue(this.Property.GetValue(dcState), result);
|
||||
}
|
||||
|
||||
return await dc.EndDialogAsync(result, cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
|
|
|
@ -18,8 +18,6 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
[JsonProperty("$kind")]
|
||||
public const string DeclarativeType = "Microsoft.GotoAction";
|
||||
|
||||
private Expression disabled;
|
||||
|
||||
public GotoAction(string actionId = null, [CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0)
|
||||
{
|
||||
this.RegisterSourceLocation(callerPath, callerLine);
|
||||
|
@ -30,7 +28,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
/// Gets or sets the action Id to goto.
|
||||
/// </summary>
|
||||
/// <value>The action Id.</value>
|
||||
public string ActionId { get; set; }
|
||||
public StringExpression ActionId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets an optional expression which if is true will disable this action.
|
||||
|
@ -42,11 +40,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
/// A boolean expression.
|
||||
/// </value>
|
||||
[JsonProperty("disabled")]
|
||||
public string Disabled
|
||||
{
|
||||
get { return disabled?.ToString(); }
|
||||
set { disabled = value != null ? new ExpressionEngine().Parse(value) : null; }
|
||||
}
|
||||
public BoolExpression Disabled { get; set; }
|
||||
|
||||
public override async Task<DialogTurnResult> BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
|
@ -55,7 +49,9 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
throw new ArgumentException($"{nameof(options)} cannot be a cancellation token");
|
||||
}
|
||||
|
||||
if (this.disabled != null && (bool?)this.disabled.TryEvaluate(dc.GetState()).value == true)
|
||||
var dcState = dc.GetState();
|
||||
|
||||
if (this.Disabled != null && this.Disabled.GetValue(dcState) == true)
|
||||
{
|
||||
return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
@ -64,7 +60,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
var actionScopeResult = new ActionScopeResult()
|
||||
{
|
||||
ActionScopeCommand = ActionScopeCommands.GotoAction,
|
||||
ActionId = this.ActionId ?? throw new ArgumentNullException(nameof(ActionId))
|
||||
ActionId = this.ActionId?.GetValue(dcState) ?? throw new ArgumentNullException(nameof(ActionId))
|
||||
};
|
||||
|
||||
return await dc.EndDialogAsync(result: actionScopeResult, cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
|
|
|
@ -10,9 +10,7 @@ using System.Runtime.CompilerServices;
|
|||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Bot.Builder.Dialogs.Adaptive.Templates;
|
||||
using Microsoft.Bot.Builder.TraceExtensions;
|
||||
using Microsoft.Bot.Expressions;
|
||||
using Microsoft.Bot.Schema;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
|
@ -28,15 +26,13 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
[JsonProperty("$kind")]
|
||||
public const string DeclarativeType = "Microsoft.HttpRequest";
|
||||
|
||||
private Expression disabled;
|
||||
|
||||
public HttpRequest(HttpMethod method, string url, string inputProperty, Dictionary<string, string> headers = null, JObject body = null, [CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0)
|
||||
public HttpRequest(HttpMethod method, string url, Dictionary<string, StringExpression> headers = null, object body = null, [CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0)
|
||||
{
|
||||
this.RegisterSourceLocation(callerPath, callerLine);
|
||||
this.Method = method;
|
||||
this.Url = url ?? throw new ArgumentNullException(nameof(url));
|
||||
this.Headers = headers;
|
||||
this.Body = body;
|
||||
this.Body = JToken.FromObject(body);
|
||||
}
|
||||
|
||||
[JsonConstructor]
|
||||
|
@ -111,27 +107,51 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
/// A boolean expression.
|
||||
/// </value>
|
||||
[JsonProperty("disabled")]
|
||||
public string Disabled
|
||||
{
|
||||
get { return disabled?.ToString(); }
|
||||
set { disabled = value != null ? new ExpressionEngine().Parse(value) : null; }
|
||||
}
|
||||
public BoolExpression Disabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the HttpMethod to use.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// HttpMethod.
|
||||
/// </value>
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
[JsonProperty("method")]
|
||||
public HttpMethod Method { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Url.
|
||||
/// </summary>
|
||||
/// <value>url.</value>
|
||||
[JsonProperty("url")]
|
||||
public string Url { get; set; }
|
||||
public StringExpression Url { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets headers.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// Headers.
|
||||
/// </value>
|
||||
[JsonProperty("headers")]
|
||||
public Dictionary<string, string> Headers { get; set; }
|
||||
public Dictionary<string, StringExpression> Headers { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets body payload.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// Body payload.
|
||||
/// </value>
|
||||
[JsonProperty("body")]
|
||||
public JToken Body { get; set; }
|
||||
public ValueExpression Body { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the ResponseType.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The ResponseType.
|
||||
/// </value>
|
||||
[JsonProperty("responseType")]
|
||||
public ResponseTypes ResponseType { get; set; } = ResponseTypes.Json;
|
||||
public EnumExpression<ResponseTypes> ResponseType { get; set; } = ResponseTypes.Json;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the property expression to store the HTTP response in.
|
||||
|
@ -145,7 +165,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
/// The property expression to store the HTTP response in.
|
||||
/// </value>
|
||||
[JsonProperty("resultProperty")]
|
||||
public string ResultProperty { get; set; }
|
||||
public StringExpression ResultProperty { get; set; }
|
||||
|
||||
public override async Task<DialogTurnResult> BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
|
@ -154,7 +174,9 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
throw new ArgumentException($"{nameof(options)} cannot be a cancellation token");
|
||||
}
|
||||
|
||||
if (this.disabled != null && (bool?)this.disabled.TryEvaluate(dc.GetState()).value == true)
|
||||
var dcState = dc.GetState();
|
||||
|
||||
if (this.Disabled != null && this.Disabled.GetValue(dcState) == true)
|
||||
{
|
||||
return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
@ -167,13 +189,22 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
JToken instanceBody = null;
|
||||
if (this.Body != null)
|
||||
{
|
||||
instanceBody = (JToken)this.Body.DeepClone();
|
||||
var (body, err) = this.Body.TryGetValue(dcState);
|
||||
if (err != null)
|
||||
{
|
||||
throw new ArgumentException(err);
|
||||
}
|
||||
|
||||
var instanceHeaders = Headers == null ? null : new Dictionary<string, string>(Headers);
|
||||
var instanceUrl = this.Url;
|
||||
instanceBody = (JToken)JToken.FromObject(body).DeepClone();
|
||||
}
|
||||
|
||||
instanceUrl = await new TextTemplate(this.Url).BindToData(dc.Context, dc.GetState()).ConfigureAwait(false);
|
||||
var instanceHeaders = Headers == null ? null : Headers.ToDictionary(kv => kv.Key, kv => kv.Value.GetValue(dcState));
|
||||
|
||||
var (instanceUrl, instanceUrlError) = this.Url.TryGetValue(dcState);
|
||||
if (instanceUrlError != null)
|
||||
{
|
||||
throw new ArgumentException(instanceUrlError);
|
||||
}
|
||||
|
||||
// Bind each string token to the data in state
|
||||
if (instanceBody != null)
|
||||
|
@ -186,9 +217,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
{
|
||||
foreach (var unit in instanceHeaders)
|
||||
{
|
||||
client.DefaultRequestHeaders.Add(
|
||||
await new TextTemplate(unit.Key).BindToData(dc.Context, dc.GetState()),
|
||||
await new TextTemplate(unit.Value).BindToData(dc.Context, dc.GetState()));
|
||||
client.DefaultRequestHeaders.TryAddWithoutValidation(unit.Key, unit.Value);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -266,7 +295,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
|
||||
object content = (object)await response.Content.ReadAsStringAsync();
|
||||
|
||||
switch (this.ResponseType)
|
||||
switch (this.ResponseType.GetValue(dcState))
|
||||
{
|
||||
case ResponseTypes.Activity:
|
||||
var activity = JsonConvert.DeserializeObject<Activity>((string)content);
|
||||
|
@ -306,7 +335,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
|
||||
if (this.ResultProperty != null)
|
||||
{
|
||||
dc.GetState().SetValue(this.ResultProperty, requestResult);
|
||||
dcState.SetValue(this.ResultProperty.GetValue(dcState), requestResult);
|
||||
}
|
||||
|
||||
// return the actionResult as the result of this operation
|
||||
|
@ -320,6 +349,8 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
|
||||
private async Task ReplaceJTokenRecursively(DialogContext dc, JToken token)
|
||||
{
|
||||
var dcState = dc.GetState();
|
||||
|
||||
switch (token.Type)
|
||||
{
|
||||
case JTokenType.Object:
|
||||
|
@ -331,7 +362,8 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
break;
|
||||
|
||||
case JTokenType.Array:
|
||||
foreach (var child in token.Children())
|
||||
// NOTE: ToList() is required because JToken.Replace will break the enumeration.
|
||||
foreach (var child in token.Children().ToList())
|
||||
{
|
||||
await ReplaceJTokenRecursively(dc, child);
|
||||
}
|
||||
|
@ -348,17 +380,10 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
var text = token.ToString();
|
||||
|
||||
// if it is a "{bindingpath}" then run through expression engine and treat as a value
|
||||
if (text.StartsWith("{") && text.EndsWith("}"))
|
||||
var (result, error) = new ValueExpression(text).TryGetValue(dcState);
|
||||
if (error == null)
|
||||
{
|
||||
text = text.Trim('{', '}');
|
||||
var (val, error) = new ExpressionEngine().Parse(text).TryEvaluate(dc.GetState());
|
||||
token.Replace(new JValue(val));
|
||||
}
|
||||
else
|
||||
{
|
||||
// use text template binding to bind in place to a string
|
||||
var temp = await new TextTemplate(text).BindToData(dc.Context, dc.GetState());
|
||||
token.Replace(new JValue(temp));
|
||||
token.Replace(JToken.FromObject(result));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -20,9 +20,6 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
[JsonProperty("$kind")]
|
||||
public const string DeclarativeType = "Microsoft.IfCondition";
|
||||
|
||||
private Expression condition;
|
||||
private Expression disabled;
|
||||
|
||||
private ActionScope trueScope;
|
||||
private ActionScope falseScope;
|
||||
|
||||
|
@ -43,11 +40,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
/// The memory expression.
|
||||
/// </value>
|
||||
[JsonProperty("condition")]
|
||||
public string Condition
|
||||
{
|
||||
get { return condition?.ToString(); }
|
||||
set { condition = value != null ? new ExpressionEngine().Parse(value) : null; }
|
||||
}
|
||||
public BoolExpression Condition { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets an optional expression which if is true will disable this action.
|
||||
|
@ -59,11 +52,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
/// A boolean expression.
|
||||
/// </value>
|
||||
[JsonProperty("disabled")]
|
||||
public string Disabled
|
||||
{
|
||||
get { return disabled?.ToString(); }
|
||||
set { disabled = value != null ? new ExpressionEngine().Parse(value) : null; }
|
||||
}
|
||||
public BoolExpression Disabled { get; set; }
|
||||
|
||||
[JsonProperty("actions")]
|
||||
public List<Dialog> Actions { get; set; } = new List<Dialog>();
|
||||
|
@ -110,7 +99,9 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
throw new ArgumentException($"{nameof(options)} cannot be a cancellation token");
|
||||
}
|
||||
|
||||
if (this.disabled != null && (bool?)this.disabled.TryEvaluate(dc.GetState()).value == true)
|
||||
var dcState = dc.GetState();
|
||||
|
||||
if (this.Disabled != null && this.Disabled.GetValue(dcState) == true)
|
||||
{
|
||||
return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
@ -118,9 +109,8 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
// Ensure planning context
|
||||
if (dc is SequenceContext planning)
|
||||
{
|
||||
var (value, error) = condition.TryEvaluate(dc.GetState());
|
||||
var conditionResult = error == null && value != null && (bool)value;
|
||||
if (conditionResult == true && TrueScope.Actions.Any())
|
||||
var (conditionResult, error) = this.Condition.TryGetValue(dcState);
|
||||
if (error == null && conditionResult == true && TrueScope.Actions.Any())
|
||||
{
|
||||
// replace dialog with If True Action Scope
|
||||
return await dc.ReplaceDialogAsync(this.TrueScope.Id, cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
|
|
|
@ -19,8 +19,6 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
[JsonProperty("$kind")]
|
||||
public const string DeclarativeType = "Microsoft.InitProperty";
|
||||
|
||||
private Expression disabled;
|
||||
|
||||
[JsonConstructor]
|
||||
public InitProperty([CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0)
|
||||
: base()
|
||||
|
@ -38,11 +36,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
/// A boolean expression.
|
||||
/// </value>
|
||||
[JsonProperty("disabled")]
|
||||
public string Disabled
|
||||
{
|
||||
get { return disabled?.ToString(); }
|
||||
set { disabled = value != null ? new ExpressionEngine().Parse(value) : null; }
|
||||
}
|
||||
public BoolExpression Disabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets property path to initialize.
|
||||
|
@ -51,7 +45,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
/// Property path to initialize.
|
||||
/// </value>
|
||||
[JsonProperty("property")]
|
||||
public string Property { get; set; }
|
||||
public StringExpression Property { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets type, either Array or Object.
|
||||
|
@ -69,7 +63,9 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
throw new ArgumentException($"{nameof(options)} cannot be a cancellation token");
|
||||
}
|
||||
|
||||
if (this.disabled != null && (bool?)this.disabled.TryEvaluate(dc.GetState()).value == true)
|
||||
var dcState = dc.GetState();
|
||||
|
||||
if (this.Disabled != null && this.Disabled.GetValue(dcState) == true)
|
||||
{
|
||||
return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
@ -77,13 +73,15 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
// Ensure planning context
|
||||
if (dc is SequenceContext planning)
|
||||
{
|
||||
var state = dcState;
|
||||
|
||||
switch (Type.ToLower())
|
||||
{
|
||||
case "array":
|
||||
dc.GetState().SetValue(this.Property, new JArray());
|
||||
state.SetValue(this.Property.GetValue(state), new JArray());
|
||||
break;
|
||||
case "object":
|
||||
dc.GetState().SetValue(this.Property, new JObject());
|
||||
state.SetValue(this.Property.GetValue(state), new JObject());
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,8 +21,6 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
[JsonProperty("$kind")]
|
||||
public const string DeclarativeType = "Microsoft.LogAction";
|
||||
|
||||
private Expression disabled;
|
||||
|
||||
[JsonConstructor]
|
||||
public LogAction(string text = null, [CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0)
|
||||
{
|
||||
|
@ -43,11 +41,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
/// A boolean expression.
|
||||
/// </value>
|
||||
[JsonProperty("disabled")]
|
||||
public string Disabled
|
||||
{
|
||||
get { return disabled?.ToString(); }
|
||||
set { disabled = value != null ? new ExpressionEngine().Parse(value) : null; }
|
||||
}
|
||||
public BoolExpression Disabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets lG expression to log.
|
||||
|
@ -65,14 +59,14 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
/// Whether a TraceActivity will be sent in addition to console log.
|
||||
/// </value>
|
||||
[JsonProperty("traceActivity")]
|
||||
public bool TraceActivity { get; set; } = false;
|
||||
public BoolExpression TraceActivity { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a label to use when describing a trace activity.
|
||||
/// </summary>
|
||||
/// <value>The label to use. (default is the id of the action).</value>
|
||||
[JsonProperty]
|
||||
public string Label { get; set; }
|
||||
public StringExpression Label { get; set; }
|
||||
|
||||
public override async Task<DialogTurnResult> BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
|
@ -81,18 +75,20 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
throw new ArgumentException($"{nameof(options)} cannot be a cancellation token");
|
||||
}
|
||||
|
||||
if (this.disabled != null && (bool?)this.disabled.TryEvaluate(dc.GetState()).value == true)
|
||||
var dcState = dc.GetState();
|
||||
|
||||
if (this.Disabled != null && this.Disabled.GetValue(dcState) == true)
|
||||
{
|
||||
return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
var text = await Text.BindToData(dc.Context, dc.GetState()).ConfigureAwait(false);
|
||||
var text = await Text.BindToData(dc.Context, dcState).ConfigureAwait(false);
|
||||
|
||||
System.Diagnostics.Trace.TraceInformation(text);
|
||||
|
||||
if (this.TraceActivity)
|
||||
if (this.TraceActivity.GetValue(dcState))
|
||||
{
|
||||
var traceActivity = Activity.CreateTraceActivity(name: "Log", valueType: "Text", value: text, label: this.Label ?? dc.Parent?.ActiveDialog?.Id);
|
||||
var traceActivity = Activity.CreateTraceActivity(name: "Log", valueType: "Text", value: text, label: this.Label?.GetValue(dcState) ?? dc.Parent?.ActiveDialog?.Id);
|
||||
await dc.Context.SendActivityAsync(traceActivity, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ using Newtonsoft.Json;
|
|||
namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
||||
{
|
||||
/// <summary>
|
||||
/// Property Assignment.
|
||||
/// Property Assignment (used in SetProperty and SetProperties actions).
|
||||
/// </summary>
|
||||
public class PropertyAssignment
|
||||
{
|
||||
|
@ -15,13 +15,13 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
/// </summary>
|
||||
/// <value>A property path expression.</value>
|
||||
[JsonProperty("property")]
|
||||
public string Property { get; set; }
|
||||
public StringExpression Property { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the value to set.
|
||||
/// </summary>
|
||||
/// <value>Value expression.</value>
|
||||
[JsonProperty("value")]
|
||||
public string Value { get; set; }
|
||||
public ValueExpression Value { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,8 +19,6 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
[JsonProperty("$kind")]
|
||||
public const string DeclarativeType = "Microsoft.RepeatDialog";
|
||||
|
||||
private Expression disabled;
|
||||
|
||||
[JsonConstructor]
|
||||
public RepeatDialog([CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0)
|
||||
: base()
|
||||
|
@ -38,11 +36,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
/// A boolean expression.
|
||||
/// </value>
|
||||
[JsonProperty("disabled")]
|
||||
public string Disabled
|
||||
{
|
||||
get { return disabled?.ToString(); }
|
||||
set { disabled = value != null ? new ExpressionEngine().Parse(value) : null; }
|
||||
}
|
||||
public BoolExpression Disabled { get; set; }
|
||||
|
||||
public override async Task<DialogTurnResult> BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
|
@ -51,7 +45,9 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
throw new ArgumentException($"{nameof(options)} cannot be a cancellation token");
|
||||
}
|
||||
|
||||
if (this.disabled != null && (bool?)this.disabled.TryEvaluate(dc.GetState()).value == true)
|
||||
var dcState = dc.GetState();
|
||||
|
||||
if (this.Disabled != null && this.Disabled.GetValue(dcState) == true)
|
||||
{
|
||||
return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
@ -61,17 +57,17 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
|
||||
var targetDialogId = dc.Parent.ActiveDialog.Id;
|
||||
|
||||
var repeatedIds = dc.GetState().GetValue<List<string>>(TurnPath.REPEATEDIDS, () => new List<string>());
|
||||
var repeatedIds = dcState.GetValue<List<string>>(TurnPath.REPEATEDIDS, () => new List<string>());
|
||||
if (repeatedIds.Contains(targetDialogId))
|
||||
{
|
||||
throw new ArgumentException($"Recursive loop detected, {targetDialogId} cannot be repeated twice in one turn.");
|
||||
}
|
||||
|
||||
repeatedIds.Add(targetDialogId);
|
||||
dc.GetState().SetValue(TurnPath.REPEATEDIDS, repeatedIds);
|
||||
dcState.SetValue(TurnPath.REPEATEDIDS, repeatedIds);
|
||||
|
||||
// set the activity processed state (default is true)
|
||||
dc.GetState().SetValue(TurnPath.ACTIVITYPROCESSED, this.ActivityProcessed);
|
||||
dcState.SetValue(TurnPath.ACTIVITYPROCESSED, this.ActivityProcessed);
|
||||
|
||||
var turnResult = await dc.Parent.ReplaceDialogAsync(dc.Parent.ActiveDialog.Id, boundOptions, cancellationToken).ConfigureAwait(false);
|
||||
turnResult.ParentEnded = true;
|
||||
|
|
|
@ -19,10 +19,8 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
[JsonProperty("$kind")]
|
||||
public const string DeclarativeType = "Microsoft.ReplaceDialog";
|
||||
|
||||
private Expression disabled;
|
||||
|
||||
[JsonConstructor]
|
||||
public ReplaceDialog(string dialogIdToCall = null, IDictionary<string, string> options = null, [CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0)
|
||||
public ReplaceDialog(string dialogIdToCall = null, object options = null, [CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0)
|
||||
: base(dialogIdToCall, options)
|
||||
{
|
||||
this.RegisterSourceLocation(callerPath, callerLine);
|
||||
|
@ -38,11 +36,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
/// A boolean expression.
|
||||
/// </value>
|
||||
[JsonProperty("disabled")]
|
||||
public string Disabled
|
||||
{
|
||||
get { return disabled?.ToString(); }
|
||||
set { disabled = value != null ? new ExpressionEngine().Parse(value) : null; }
|
||||
}
|
||||
public BoolExpression Disabled { get; set; }
|
||||
|
||||
public override async Task<DialogTurnResult> BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
|
@ -51,7 +45,9 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
throw new ArgumentException($"{nameof(options)} cannot be a cancellation token");
|
||||
}
|
||||
|
||||
if (this.disabled != null && (bool?)this.disabled.TryEvaluate(dc.GetState()).value == true)
|
||||
var dcState = dc.GetState();
|
||||
|
||||
if (this.Disabled != null && this.Disabled.GetValue(dcState) == true)
|
||||
{
|
||||
return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
@ -62,7 +58,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
var boundOptions = BindOptions(dc, options);
|
||||
|
||||
// set the activity processed state (default is true)
|
||||
dc.GetState().SetValue(TurnPath.ACTIVITYPROCESSED, this.ActivityProcessed);
|
||||
dcState.SetValue(TurnPath.ACTIVITYPROCESSED, this.ActivityProcessed);
|
||||
|
||||
// replace dialog with bound options passed in as the options
|
||||
return await dc.ReplaceDialogAsync(dialog.Id, options: boundOptions, cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
|
|
|
@ -21,8 +21,6 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
[JsonProperty("$kind")]
|
||||
public const string DeclarativeType = "Microsoft.SendActivity";
|
||||
|
||||
private Expression disabled;
|
||||
|
||||
public SendActivity(Activity activity, [CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0)
|
||||
{
|
||||
this.RegisterSourceLocation(callerPath, callerLine);
|
||||
|
@ -46,11 +44,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
/// A boolean expression.
|
||||
/// </value>
|
||||
[JsonProperty("disabled")]
|
||||
public string Disabled
|
||||
{
|
||||
get { return disabled?.ToString(); }
|
||||
set { disabled = value != null ? new ExpressionEngine().Parse(value) : null; }
|
||||
}
|
||||
public BoolExpression Disabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets template for the activity.
|
||||
|
@ -68,12 +62,14 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
throw new ArgumentException($"{nameof(options)} cannot be a cancellation token");
|
||||
}
|
||||
|
||||
if (this.disabled != null && (bool?)this.disabled.TryEvaluate(dc.GetState()).value == true)
|
||||
var dcState = dc.GetState();
|
||||
|
||||
if (this.Disabled != null && this.Disabled.GetValue(dcState) == true)
|
||||
{
|
||||
return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
var activity = await Activity.BindToData(dc.Context, dc.GetState()).ConfigureAwait(false);
|
||||
var activity = await Activity.BindToData(dc.Context, dcState).ConfigureAwait(false);
|
||||
ResourceResponse response = null;
|
||||
if (activity.Type != "message"
|
||||
|| !string.IsNullOrEmpty(activity.Text)
|
||||
|
|
|
@ -20,8 +20,6 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
[JsonProperty("$kind")]
|
||||
public const string DeclarativeType = "Microsoft.SetProperties";
|
||||
|
||||
private Expression disabled;
|
||||
|
||||
[JsonConstructor]
|
||||
public SetProperties([CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0)
|
||||
: base()
|
||||
|
@ -39,11 +37,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
/// A boolean expression.
|
||||
/// </value>
|
||||
[JsonProperty("disabled")]
|
||||
public string Disabled
|
||||
{
|
||||
get { return disabled?.ToString(); }
|
||||
set { disabled = value != null ? new ExpressionEngine().Parse(value) : null; }
|
||||
}
|
||||
public BoolExpression Disabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets additional property assignments.
|
||||
|
@ -61,21 +55,22 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
throw new ArgumentException($"{nameof(options)} cannot be a cancellation token");
|
||||
}
|
||||
|
||||
if (this.disabled != null && (bool?)this.disabled.TryEvaluate(dc.GetState()).value == true)
|
||||
var dcState = dc.GetState();
|
||||
|
||||
if (this.Disabled != null && this.Disabled.GetValue(dcState) == true)
|
||||
{
|
||||
return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
foreach (var propValue in this.Assignments)
|
||||
{
|
||||
var valexp = new ExpressionEngine().Parse(propValue.Value);
|
||||
var (value, valueError) = valexp.TryEvaluate(dc.GetState());
|
||||
var (value, valueError) = propValue.Value.TryGetValue(dcState);
|
||||
if (valueError != null)
|
||||
{
|
||||
throw new Exception($"Expression evaluation resulted in an error. Expression: {valexp.ToString()}. Error: {valueError}");
|
||||
throw new Exception($"Expression evaluation resulted in an error. Expression: {propValue.Value.ToString()}. Error: {valueError}");
|
||||
}
|
||||
|
||||
dc.GetState().SetValue(propValue.Property, value);
|
||||
dcState.SetValue(propValue.Property.GetValue(dcState), value);
|
||||
}
|
||||
|
||||
return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
|
|
|
@ -5,6 +5,7 @@ using System;
|
|||
using System.Runtime.CompilerServices;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Bot.Builder.Dialogs.Declarative;
|
||||
using Microsoft.Bot.Expressions;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
|
@ -18,9 +19,6 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
[JsonProperty("$kind")]
|
||||
public const string DeclarativeType = "Microsoft.SetProperty";
|
||||
|
||||
private Expression value;
|
||||
private Expression disabled;
|
||||
|
||||
[JsonConstructor]
|
||||
public SetProperty([CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0)
|
||||
: base()
|
||||
|
@ -38,11 +36,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
/// A boolean expression.
|
||||
/// </value>
|
||||
[JsonProperty("disabled")]
|
||||
public string Disabled
|
||||
{
|
||||
get { return disabled?.ToString(); }
|
||||
set { disabled = value != null ? new ExpressionEngine().Parse(value) : null; }
|
||||
}
|
||||
public BoolExpression Disabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets property path to put the value in.
|
||||
|
@ -51,7 +45,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
/// Property path to put the value in.
|
||||
/// </value>
|
||||
[JsonProperty("property")]
|
||||
public string Property { get; set; }
|
||||
public StringExpression Property { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the expression to get the value to put into property path.
|
||||
|
@ -60,11 +54,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
/// The expression to get the value to put into property path.
|
||||
/// </value>
|
||||
[JsonProperty("value")]
|
||||
public string Value
|
||||
{
|
||||
get { return value?.ToString(); }
|
||||
set { this.value = (value != null) ? new ExpressionEngine().Parse(value) : null; }
|
||||
}
|
||||
public ValueExpression Value { get; set; }
|
||||
|
||||
public override async Task<DialogTurnResult> BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
|
@ -73,21 +63,28 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
throw new ArgumentException($"{nameof(options)} cannot be a cancellation token");
|
||||
}
|
||||
|
||||
if (this.disabled != null && (bool?)this.disabled.TryEvaluate(dc.GetState()).value == true)
|
||||
var dcState = dc.GetState();
|
||||
if (this.Disabled != null && this.Disabled.GetValue(dcState))
|
||||
{
|
||||
return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
// SetProperty evaluates the "Value" expression and returns it as the result of the dialog
|
||||
var (value, valueError) = this.value.TryEvaluate(dc.GetState());
|
||||
object value = null;
|
||||
if (this.Value != null)
|
||||
{
|
||||
var (val, valueError) = this.Value.TryGetValue(dcState);
|
||||
if (valueError != null)
|
||||
{
|
||||
throw new Exception($"Expression evaluation resulted in an error. Expression: {this.Value.ToString()}. Error: {valueError}");
|
||||
}
|
||||
|
||||
dc.GetState().SetValue(this.Property, value);
|
||||
value = val;
|
||||
}
|
||||
|
||||
dc.GetState().SetValue(DialogPath.Retries, 0);
|
||||
dcState.SetValue(this.Property.GetValue(dcState), value);
|
||||
|
||||
dcState.SetValue(DialogPath.Retries, 0);
|
||||
return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
|
|
|
@ -20,9 +20,6 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
[JsonProperty("$kind")]
|
||||
public const string DeclarativeType = "Microsoft.SignOutUser";
|
||||
|
||||
private Expression userId;
|
||||
private Expression disabled;
|
||||
|
||||
[JsonConstructor]
|
||||
public SignOutUser([CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0)
|
||||
{
|
||||
|
@ -39,29 +36,21 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
/// A boolean expression.
|
||||
/// </value>
|
||||
[JsonProperty("disabled")]
|
||||
public string Disabled
|
||||
{
|
||||
get { return disabled?.ToString(); }
|
||||
set { disabled = value != null ? new ExpressionEngine().Parse(value) : null; }
|
||||
}
|
||||
public BoolExpression Disabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the expression which resolves to the activityId to update.
|
||||
/// </summary>
|
||||
/// <value>Expression to userId. If there is no expression, then the current user.id will be used.</value>
|
||||
[JsonProperty("userId")]
|
||||
public string UserId
|
||||
{
|
||||
get { return userId?.ToString(); }
|
||||
set { this.userId = (value != null) ? new ExpressionEngine().Parse(value) : null; }
|
||||
}
|
||||
public StringExpression UserId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the name of the OAuth connection.
|
||||
/// </summary>
|
||||
/// <value>The name of the OAuth connection.</value>
|
||||
[JsonProperty("connectionName")]
|
||||
public string ConnectionName { get; set; }
|
||||
public StringExpression ConnectionName { get; set; }
|
||||
|
||||
public override async Task<DialogTurnResult> BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
|
@ -70,24 +59,22 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
throw new ArgumentException($"{nameof(options)} cannot be a cancellation token");
|
||||
}
|
||||
|
||||
if (this.disabled != null && (bool?)this.disabled.TryEvaluate(dc.GetState()).value == true)
|
||||
var dcState = dc.GetState();
|
||||
|
||||
if (this.Disabled != null && this.Disabled.GetValue(dcState) == true)
|
||||
{
|
||||
return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
string userId = null;
|
||||
var (result, error) = new ExpressionEngine().Parse(this.UserId).TryEvaluate(dc.GetState());
|
||||
if (result != null)
|
||||
{
|
||||
userId = result as string;
|
||||
}
|
||||
string userId = this.UserId?.GetValue(dcState);
|
||||
|
||||
if (!(dc.Context.Adapter is IUserTokenProvider adapter))
|
||||
{
|
||||
throw new InvalidOperationException("SignoutUser(): not supported by the current adapter");
|
||||
}
|
||||
|
||||
await adapter.SignOutUserAsync(dc.Context, this.ConnectionName, (string)userId, cancellationToken).ConfigureAwait(false);
|
||||
var connectionName = this.ConnectionName?.GetValue(dcState);
|
||||
await adapter.SignOutUserAsync(dc.Context, connectionName, (string)userId, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
|
|
@ -22,8 +22,6 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
|
||||
private Dictionary<string, Expression> caseExpressions = null;
|
||||
|
||||
private Expression condition;
|
||||
private Expression disabled;
|
||||
private ActionScope defaultScope;
|
||||
|
||||
[JsonConstructor]
|
||||
|
@ -34,17 +32,13 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets condition expression against memory Example: "user.age > 18".
|
||||
/// Gets or sets value expression against memory Example: "user.age".
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// Condition expression against memory Example: "user.age > 18".
|
||||
/// Value Expression against memory. This value expression will be combined with value expression in case statements to make a bool expression.
|
||||
/// </value>
|
||||
[JsonProperty("condition")]
|
||||
public string Condition
|
||||
{
|
||||
get { return condition?.ToString(); }
|
||||
set { condition = (value != null) ? new ExpressionEngine().Parse(value) : null; }
|
||||
}
|
||||
public ValueExpression Condition { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets an optional expression which if is true will disable this action.
|
||||
|
@ -56,11 +50,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
/// A boolean expression.
|
||||
/// </value>
|
||||
[JsonProperty("disabled")]
|
||||
public string Disabled
|
||||
{
|
||||
get { return disabled?.ToString(); }
|
||||
set { disabled = value != null ? new ExpressionEngine().Parse(value) : null; }
|
||||
}
|
||||
public BoolExpression Disabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets default case.
|
||||
|
@ -113,7 +103,9 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
throw new ArgumentException($"{nameof(options)} cannot be a cancellation token");
|
||||
}
|
||||
|
||||
if (this.disabled != null && (bool?)this.disabled.TryEvaluate(dc.GetState()).value == true)
|
||||
var dcState = dc.GetState();
|
||||
|
||||
if (this.Disabled != null && this.Disabled.GetValue(dcState) == true)
|
||||
{
|
||||
return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
@ -127,13 +119,13 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
{
|
||||
this.caseExpressions = new Dictionary<string, Expression>();
|
||||
|
||||
foreach (var c in this.Cases)
|
||||
foreach (var cse in this.Cases)
|
||||
{
|
||||
// Values for cases are always coerced to string
|
||||
var caseCondition = Expression.EqualsExpression(this.condition, c.CreateValueExpression());
|
||||
var caseCondition = Expression.EqualsExpression(this.Condition.ToExpression(), cse.CreateValueExpression());
|
||||
|
||||
// Map of expression to actions
|
||||
this.caseExpressions[c.Value] = caseCondition;
|
||||
this.caseExpressions[cse.Value] = caseCondition;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -142,7 +134,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
|
||||
foreach (var caseScope in this.Cases)
|
||||
{
|
||||
var (value, error) = this.caseExpressions[caseScope.Value].TryEvaluate(dc.GetState());
|
||||
var (value, error) = this.caseExpressions[caseScope.Value].TryEvaluate(dcState);
|
||||
|
||||
if (error != null)
|
||||
{
|
||||
|
|
|
@ -19,8 +19,6 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
[JsonProperty("$kind")]
|
||||
public const string DeclarativeType = "Microsoft.TraceActivity";
|
||||
|
||||
private Expression disabled;
|
||||
|
||||
[JsonConstructor]
|
||||
public TraceActivity([CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0)
|
||||
{
|
||||
|
@ -37,11 +35,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
/// A boolean expression.
|
||||
/// </value>
|
||||
[JsonProperty("disabled")]
|
||||
public string Disabled
|
||||
{
|
||||
get { return disabled?.ToString(); }
|
||||
set { disabled = value != null ? new ExpressionEngine().Parse(value) : null; }
|
||||
}
|
||||
public BoolExpression Disabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets name of the trace activity.
|
||||
|
@ -50,7 +44,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
/// Name of the trace activity.
|
||||
/// </value>
|
||||
[JsonProperty("name")]
|
||||
public string Name { get; set; }
|
||||
public StringExpression Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets value type of the trace activity.
|
||||
|
@ -59,7 +53,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
/// Value type of the trace activity.
|
||||
/// </value>
|
||||
[JsonProperty("valueType")]
|
||||
public string ValueType { get; set; }
|
||||
public StringExpression ValueType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets value expression to send as the value.
|
||||
|
@ -68,14 +62,14 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
/// Property binding to memory to send as the value.
|
||||
/// </value>
|
||||
[JsonProperty("value")]
|
||||
public string Value { get; set; }
|
||||
public ValueExpression Value { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a label to use when describing a trace activity.
|
||||
/// </summary>
|
||||
/// <value>The label to use. (default will use Name or parent dialog.id).</value>
|
||||
[JsonProperty]
|
||||
public string Label { get; set; }
|
||||
public StringExpression Label { get; set; }
|
||||
|
||||
public override async Task<DialogTurnResult> BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
|
@ -84,22 +78,34 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
throw new ArgumentException($"{nameof(options)} cannot be a cancellation token");
|
||||
}
|
||||
|
||||
if (this.disabled != null && (bool?)this.disabled.TryEvaluate(dc.GetState()).value == true)
|
||||
var dcState = dc.GetState();
|
||||
|
||||
if (this.Disabled != null && this.Disabled.GetValue(dcState) == true)
|
||||
{
|
||||
return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
object value = null;
|
||||
if (!string.IsNullOrEmpty(this.Value))
|
||||
if (this.Value != null)
|
||||
{
|
||||
value = dc.GetState().GetValue<object>(this.Value);
|
||||
var (val, valError) = this.Value.TryGetValue(dcState);
|
||||
if (valError != null)
|
||||
{
|
||||
throw new Exception(valError);
|
||||
}
|
||||
|
||||
value = val;
|
||||
}
|
||||
else
|
||||
{
|
||||
value = dc.GetState().GetMemorySnapshot();
|
||||
value = dcState.GetMemorySnapshot();
|
||||
}
|
||||
|
||||
var traceActivity = Activity.CreateTraceActivity(this.Name ?? "Trace", valueType: this.ValueType ?? "State", value: value, label: this.Label ?? this.Name ?? dc.Parent?.ActiveDialog?.Id);
|
||||
var name = this.Name?.GetValue(dcState);
|
||||
var valueType = this.ValueType?.GetValue(dcState);
|
||||
var label = this.Label?.GetValue(dcState);
|
||||
|
||||
var traceActivity = Activity.CreateTraceActivity(name ?? "Trace", valueType: valueType ?? "State", value: value, label: label ?? name ?? dc.Parent?.ActiveDialog?.Id);
|
||||
await dc.Context.SendActivityAsync(traceActivity, cancellationToken).ConfigureAwait(false);
|
||||
return await dc.EndDialogAsync(traceActivity, cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
|
|
@ -20,9 +20,6 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
[JsonProperty("$kind")]
|
||||
public const string DeclarativeType = "Microsoft.UpdateActivity";
|
||||
|
||||
private Expression activityId;
|
||||
private Expression disabled;
|
||||
|
||||
public UpdateActivity(Activity activity, [CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0)
|
||||
{
|
||||
this.RegisterSourceLocation(callerPath, callerLine);
|
||||
|
@ -46,11 +43,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
/// A boolean expression.
|
||||
/// </value>
|
||||
[JsonProperty("disabled")]
|
||||
public string Disabled
|
||||
{
|
||||
get { return disabled?.ToString(); }
|
||||
set { disabled = value != null ? new ExpressionEngine().Parse(value) : null; }
|
||||
}
|
||||
public BoolExpression Disabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets template for the activity.
|
||||
|
@ -66,11 +59,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
/// </summary>
|
||||
/// <value>Expression to activityId.</value>
|
||||
[JsonProperty("activityId")]
|
||||
public string ActivityId
|
||||
{
|
||||
get { return activityId.ToString(); }
|
||||
set { activityId = new ExpressionEngine().Parse(value); }
|
||||
}
|
||||
public StringExpression ActivityId { get; set; }
|
||||
|
||||
public override async Task<DialogTurnResult> BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
|
@ -79,13 +68,15 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
throw new ArgumentException($"{nameof(options)} cannot be a cancellation token");
|
||||
}
|
||||
|
||||
if (this.disabled != null && (bool?)this.disabled.TryEvaluate(dc.GetState()).value == true)
|
||||
var dcState = dc.GetState();
|
||||
|
||||
if (this.Disabled != null && this.Disabled.GetValue(dcState) == true)
|
||||
{
|
||||
return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
var activity = await Activity.BindToData(dc.Context, dc.GetState()).ConfigureAwait(false);
|
||||
var (result, error) = activityId.TryEvaluate(dc.GetState());
|
||||
var activity = await Activity.BindToData(dc.Context, dcState).ConfigureAwait(false);
|
||||
var (result, error) = this.ActivityId.TryGetValue(dcState);
|
||||
if (error != null)
|
||||
{
|
||||
throw new ArgumentException(error);
|
||||
|
|
|
@ -5,6 +5,7 @@ using System.Collections.Generic;
|
|||
using Microsoft.Bot.Builder.AI.Luis;
|
||||
using Microsoft.Bot.Builder.Dialogs.Adaptive.Actions;
|
||||
using Microsoft.Bot.Builder.Dialogs.Adaptive.Conditions;
|
||||
using Microsoft.Bot.Builder.Dialogs.Adaptive.Converters;
|
||||
using Microsoft.Bot.Builder.Dialogs.Adaptive.Generators;
|
||||
using Microsoft.Bot.Builder.Dialogs.Adaptive.Input;
|
||||
using Microsoft.Bot.Builder.Dialogs.Adaptive.QnA;
|
||||
|
@ -14,6 +15,7 @@ using Microsoft.Bot.Builder.Dialogs.Adaptive.Selectors;
|
|||
using Microsoft.Bot.Builder.Dialogs.Adaptive.Testing;
|
||||
using Microsoft.Bot.Builder.Dialogs.Adaptive.Testing.Actions;
|
||||
using Microsoft.Bot.Builder.Dialogs.Adaptive.Testing.TestActions;
|
||||
using Microsoft.Bot.Builder.Dialogs.Choices;
|
||||
using Microsoft.Bot.Builder.Dialogs.Debugging;
|
||||
using Microsoft.Bot.Builder.Dialogs.Declarative;
|
||||
using Microsoft.Bot.Builder.Dialogs.Declarative.Converters;
|
||||
|
@ -21,6 +23,7 @@ using Microsoft.Bot.Builder.Dialogs.Declarative.Loaders;
|
|||
using Microsoft.Bot.Builder.Dialogs.Declarative.Resolvers;
|
||||
using Microsoft.Bot.Builder.Dialogs.Declarative.Types;
|
||||
using Newtonsoft.Json;
|
||||
using static Microsoft.Bot.Builder.Dialogs.Adaptive.Actions.EditArray;
|
||||
|
||||
namespace Microsoft.Bot.Builder.Dialogs.Adaptive
|
||||
{
|
||||
|
@ -167,8 +170,28 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive
|
|||
yield return new InterfaceConverter<TestAction>(refResolver, sourceMap, paths);
|
||||
yield return new InterfaceConverter<EntityRecognizer>(refResolver, sourceMap, paths);
|
||||
yield return new InterfaceConverter<ITriggerSelector>(refResolver, sourceMap, paths);
|
||||
yield return new ExpressionPropertyConverter<ChoiceSet>();
|
||||
yield return new ExpressionPropertyConverter<ExpressionProperty<List<string>>>();
|
||||
|
||||
yield return new IntExpressionConverter();
|
||||
yield return new NumberExpressionConverter();
|
||||
yield return new StringExpressionConverter();
|
||||
yield return new ValueExpressionConverter();
|
||||
yield return new BoolExpressionConverter();
|
||||
yield return new DialogExpressionConverter(refResolver, sourceMap, paths);
|
||||
|
||||
yield return new ObjectExpressionConverter<ChoiceSet>();
|
||||
yield return new ObjectExpressionConverter<ChoiceFactoryOptions>();
|
||||
yield return new ObjectExpressionConverter<FindChoicesOptions>();
|
||||
|
||||
yield return new ArrayExpressionConverter<string>();
|
||||
yield return new ArrayExpressionConverter<Choice>();
|
||||
|
||||
yield return new EnumExpressionConverter<ActionChangeType>();
|
||||
yield return new EnumExpressionConverter<ArrayChangeType>();
|
||||
yield return new EnumExpressionConverter<AttachmentOutputFormat>();
|
||||
yield return new EnumExpressionConverter<ListStyle>();
|
||||
yield return new EnumExpressionConverter<ChoiceOutputFormat>();
|
||||
|
||||
yield return new ChoiceSetConverter();
|
||||
yield return new ActivityTemplateConverter();
|
||||
yield return new JObjectConverter(refResolver);
|
||||
}
|
||||
|
|
|
@ -153,31 +153,33 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive
|
|||
|
||||
EnsureDependenciesInstalled();
|
||||
|
||||
if (!dc.GetState().ContainsKey(DialogPath.EventCounter))
|
||||
var dcState = dc.GetState();
|
||||
|
||||
if (!dcState.ContainsKey(DialogPath.EventCounter))
|
||||
{
|
||||
dc.GetState().SetValue(DialogPath.EventCounter, 0u);
|
||||
dcState.SetValue(DialogPath.EventCounter, 0u);
|
||||
}
|
||||
|
||||
if (dialogSchema != null && !dc.GetState().ContainsKey(DialogPath.RequiredProperties))
|
||||
if (dialogSchema != null && !dcState.ContainsKey(DialogPath.RequiredProperties))
|
||||
{
|
||||
// RequiredProperties control what properties must be filled in.
|
||||
// Initialize if not present from schema.
|
||||
dc.GetState().SetValue(DialogPath.RequiredProperties, dialogSchema.Required());
|
||||
dcState.SetValue(DialogPath.RequiredProperties, dialogSchema.Required());
|
||||
}
|
||||
|
||||
if (needsTracker)
|
||||
{
|
||||
if (!dc.GetState().ContainsKey(ConditionTracker))
|
||||
if (!dcState.ContainsKey(ConditionTracker))
|
||||
{
|
||||
var parser = Selector.Parser;
|
||||
foreach (var trigger in Triggers)
|
||||
{
|
||||
if (trigger.RunOnce)
|
||||
if (trigger.RunOnce && trigger.Condition != null)
|
||||
{
|
||||
var paths = dc.GetState().TrackPaths(parser.Parse(trigger.Condition).References());
|
||||
var paths = dcState.TrackPaths(trigger.Condition.ToExpression().References());
|
||||
var triggerPath = $"{ConditionTracker}.{trigger.Id}.";
|
||||
dc.GetState().SetValue(triggerPath + "paths", paths);
|
||||
dc.GetState().SetValue(triggerPath + "lastRun", 0u);
|
||||
dcState.SetValue(triggerPath + "paths", paths);
|
||||
dcState.SetValue(triggerPath + "lastRun", 0u);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -303,14 +305,16 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive
|
|||
|
||||
protected virtual async Task<bool> ProcessEventAsync(SequenceContext sequenceContext, DialogEvent dialogEvent, bool preBubble, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
var dcState = sequenceContext.GetState();
|
||||
|
||||
// Save into turn
|
||||
sequenceContext.GetState().SetValue(TurnPath.DIALOGEVENT, dialogEvent);
|
||||
dcState.SetValue(TurnPath.DIALOGEVENT, dialogEvent);
|
||||
|
||||
EnsureDependenciesInstalled();
|
||||
|
||||
// Count of events processed
|
||||
var count = sequenceContext.GetState().GetValue<uint>(DialogPath.EventCounter);
|
||||
sequenceContext.GetState().SetValue(DialogPath.EventCounter, ++count);
|
||||
var count = dcState.GetValue<uint>(DialogPath.EventCounter);
|
||||
dcState.SetValue(DialogPath.EventCounter, ++count);
|
||||
|
||||
// Look for triggered evt
|
||||
var handled = await QueueFirstMatchAsync(sequenceContext, dialogEvent, preBubble, cancellationToken).ConfigureAwait(false);
|
||||
|
@ -326,7 +330,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive
|
|||
switch (dialogEvent.Name)
|
||||
{
|
||||
case AdaptiveEvents.BeginDialog:
|
||||
if (sequenceContext.GetState().GetBoolValue(TurnPath.ACTIVITYPROCESSED) == false)
|
||||
if (dcState.GetBoolValue(TurnPath.ACTIVITYPROCESSED) == false)
|
||||
{
|
||||
// Emit leading ActivityReceived event
|
||||
var activityReceivedEvent = new DialogEvent()
|
||||
|
@ -355,7 +359,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive
|
|||
await ProcessEventAsync(sequenceContext, dialogEvent: recognizeUtteranceEvent, preBubble: true, cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
|
||||
// Emit leading RecognizedIntent event
|
||||
var recognized = sequenceContext.GetState().GetValue<RecognizerResult>(TurnPath.RECOGNIZED);
|
||||
var recognized = dcState.GetValue<RecognizerResult>(TurnPath.RECOGNIZED);
|
||||
var recognizedIntentEvent = new DialogEvent
|
||||
{
|
||||
Name = AdaptiveEvents.RecognizedIntent,
|
||||
|
@ -372,7 +376,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive
|
|||
// process the users uterrance when its continued.
|
||||
if (handled)
|
||||
{
|
||||
sequenceContext.GetState().SetValue(TurnPath.INTERRUPTED, true);
|
||||
dcState.SetValue(TurnPath.INTERRUPTED, true);
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -384,12 +388,12 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive
|
|||
// Recognize utterance
|
||||
var recognized = await OnRecognize(sequenceContext, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
sequenceContext.GetState().SetValue(TurnPath.RECOGNIZED, recognized);
|
||||
dcState.SetValue(TurnPath.RECOGNIZED, recognized);
|
||||
|
||||
var (name, score) = recognized.GetTopScoringIntent();
|
||||
sequenceContext.GetState().SetValue(TurnPath.TOPINTENT, name);
|
||||
sequenceContext.GetState().SetValue(DialogPath.LastIntent, name);
|
||||
sequenceContext.GetState().SetValue(TurnPath.TOPSCORE, score);
|
||||
dcState.SetValue(TurnPath.TOPINTENT, name);
|
||||
dcState.SetValue(DialogPath.LastIntent, name);
|
||||
dcState.SetValue(TurnPath.TOPSCORE, score);
|
||||
|
||||
if (Recognizer != null)
|
||||
{
|
||||
|
@ -407,7 +411,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive
|
|||
switch (dialogEvent.Name)
|
||||
{
|
||||
case AdaptiveEvents.BeginDialog:
|
||||
if (sequenceContext.GetState().GetBoolValue(TurnPath.ACTIVITYPROCESSED) == false)
|
||||
if (dcState.GetBoolValue(TurnPath.ACTIVITYPROCESSED) == false)
|
||||
{
|
||||
var activityReceivedEvent = new DialogEvent
|
||||
{
|
||||
|
@ -450,7 +454,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive
|
|||
// process the users uterrance when its continued.
|
||||
if (handled)
|
||||
{
|
||||
sequenceContext.GetState().SetValue(TurnPath.INTERRUPTED, true);
|
||||
dcState.SetValue(TurnPath.INTERRUPTED, true);
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -555,6 +559,8 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive
|
|||
// Is the current dialog still on the stack?
|
||||
if (sequenceContext.ActiveDialog != null)
|
||||
{
|
||||
var dcState = sequenceContext.GetState();
|
||||
|
||||
// Completed actions so continue processing entity queues
|
||||
var handled = await ProcessQueuesAsync(sequenceContext, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
|
@ -566,7 +572,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive
|
|||
else if (ShouldEnd(sequenceContext))
|
||||
{
|
||||
RestoreParentGenerator(sequenceContext.Context);
|
||||
sequenceContext.GetState().TryGetValue<object>(DefaultResultProperty, out var result);
|
||||
dcState.TryGetValue<object>(DefaultResultProperty, out var result);
|
||||
return await sequenceContext.EndDialogAsync(result, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
|
@ -620,6 +626,8 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive
|
|||
// In order ClearProperties, AssignEntity, ChooseProperties, ChooseEntity, EndOfActions.
|
||||
private async Task<bool> ProcessQueuesAsync(SequenceContext sequenceContext, CancellationToken cancellationToken)
|
||||
{
|
||||
var dcState = sequenceContext.GetState();
|
||||
|
||||
DialogEvent evt;
|
||||
var queues = EntityEvents.Read(sequenceContext);
|
||||
var changed = false;
|
||||
|
@ -642,7 +650,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive
|
|||
entity = new object[] { entity };
|
||||
}
|
||||
|
||||
sequenceContext.GetState().SetValue($"{TurnPath.RECOGNIZED}.entities.{val.Entity.Name}", entity);
|
||||
dcState.SetValue($"{TurnPath.RECOGNIZED}.entities.{val.Entity.Name}", entity);
|
||||
changed = true;
|
||||
}
|
||||
else if (queues.ChooseProperties.Any())
|
||||
|
@ -663,7 +671,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive
|
|||
queues.Write(sequenceContext);
|
||||
}
|
||||
|
||||
sequenceContext.GetState().SetValue(DialogPath.LastEvent, evt.Name);
|
||||
dcState.SetValue(DialogPath.LastEvent, evt.Name);
|
||||
var handled = await this.ProcessEventAsync(sequenceContext, dialogEvent: evt, preBubble: true, cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
if (!handled)
|
||||
{
|
||||
|
@ -690,7 +698,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive
|
|||
{
|
||||
var evt = selection.First();
|
||||
await sequenceContext.DebuggerStepAsync(evt, dialogEvent, cancellationToken).ConfigureAwait(false);
|
||||
Trace.TraceInformation($"Executing Dialog: {Id} Rule[{selection}]: {evt.GetType().Name}: {evt.GetExpression(new ExpressionEngine())}");
|
||||
Trace.TraceInformation($"Executing Dialog: {Id} Rule[{evt.Id}]: {evt.GetType().Name}: {evt.GetExpression(new ExpressionEngine())}");
|
||||
var changes = await evt.ExecuteAsync(sequenceContext).ConfigureAwait(false);
|
||||
|
||||
if (changes != null && changes.Any())
|
||||
|
@ -711,7 +719,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive
|
|||
{
|
||||
installedDependencies = true;
|
||||
|
||||
var id = 0u;
|
||||
var id = 0;
|
||||
foreach (var trigger in Triggers)
|
||||
{
|
||||
if (trigger is IDialogDependencies depends)
|
||||
|
@ -730,7 +738,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive
|
|||
if (trigger.Priority == null)
|
||||
{
|
||||
// Constant expression defined from order
|
||||
trigger.Priority = id.ToString();
|
||||
trigger.Priority = id;
|
||||
}
|
||||
|
||||
if (trigger.Id == null)
|
||||
|
@ -812,17 +820,19 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive
|
|||
// Merge new queues into existing queues of ambiguity events
|
||||
private void ProcessEntities(SequenceContext context)
|
||||
{
|
||||
var dcState = context.GetState();
|
||||
|
||||
if (dialogSchema != null)
|
||||
{
|
||||
if (context.GetState().TryGetValue<string>(DialogPath.LastEvent, out var lastEvent))
|
||||
if (dcState.TryGetValue<string>(DialogPath.LastEvent, out var lastEvent))
|
||||
{
|
||||
context.GetState().RemoveValue(DialogPath.LastEvent);
|
||||
dcState.RemoveValue(DialogPath.LastEvent);
|
||||
}
|
||||
|
||||
var queues = EntityEvents.Read(context);
|
||||
var entities = NormalizeEntities(context);
|
||||
var utterance = context.Context.Activity?.AsMessageActivity()?.Text;
|
||||
if (!context.GetState().TryGetValue<string[]>(DialogPath.ExpectedProperties, out var expected))
|
||||
if (!dcState.TryGetValue<string[]>(DialogPath.ExpectedProperties, out var expected))
|
||||
{
|
||||
expected = new string[0];
|
||||
}
|
||||
|
@ -833,9 +843,9 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive
|
|||
var unrecognized = SplitUtterance(utterance, recognized);
|
||||
|
||||
// TODO: Is this actually useful information?
|
||||
context.GetState().SetValue(TurnPath.UNRECOGNIZEDTEXT, unrecognized);
|
||||
context.GetState().SetValue(TurnPath.RECOGNIZEDENTITIES, recognized);
|
||||
var turn = context.GetState().GetValue<uint>(DialogPath.EventCounter);
|
||||
dcState.SetValue(TurnPath.UNRECOGNIZEDTEXT, unrecognized);
|
||||
dcState.SetValue(TurnPath.RECOGNIZEDENTITIES, recognized);
|
||||
var turn = dcState.GetValue<uint>(DialogPath.EventCounter);
|
||||
CombineOldEntityToProperties(queues, turn);
|
||||
queues.Write(context);
|
||||
}
|
||||
|
@ -873,11 +883,12 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive
|
|||
// Combine entity values and $instance meta-data
|
||||
private Dictionary<string, List<EntityInfo>> NormalizeEntities(SequenceContext context)
|
||||
{
|
||||
var dcState = context.GetState();
|
||||
var entityToInfo = new Dictionary<string, List<EntityInfo>>();
|
||||
var text = context.GetState().GetValue<string>(TurnPath.RECOGNIZED + ".text");
|
||||
if (context.GetState().TryGetValue<dynamic>(TurnPath.RECOGNIZED + ".entities", out var entities))
|
||||
var text = dcState.GetValue<string>(TurnPath.RECOGNIZED + ".text");
|
||||
if (dcState.TryGetValue<dynamic>(TurnPath.RECOGNIZED + ".entities", out var entities))
|
||||
{
|
||||
var turn = context.GetState().GetValue<uint>(DialogPath.EventCounter);
|
||||
var turn = dcState.GetValue<uint>(DialogPath.EventCounter);
|
||||
var metaData = entities["$instance"];
|
||||
foreach (var entry in entities)
|
||||
{
|
||||
|
@ -1070,6 +1081,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive
|
|||
|
||||
private List<EntityInfo> AddToQueues(SequenceContext context, Dictionary<string, List<EntityInfo>> entities, string[] expected, EntityEvents queues, string lastEvent)
|
||||
{
|
||||
var dcState = context.GetState();
|
||||
var candidates = (from candidate in RemoveOverlappingPerProperty(Candidates(entities, expected))
|
||||
orderby candidate.IsExpected descending
|
||||
select candidate).ToList();
|
||||
|
@ -1103,7 +1115,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive
|
|||
{
|
||||
// Resolve choice and add to queues
|
||||
queues.ChooseProperties.Dequeue();
|
||||
context.GetState().SetValue(DialogPath.ExpectedProperties, new List<string> { choice.Property });
|
||||
dcState.SetValue(DialogPath.ExpectedProperties, new List<string> { choice.Property });
|
||||
choice.IsExpected = true;
|
||||
AddMappingToQueue(choice, queues);
|
||||
mapped = true;
|
||||
|
|
|
@ -22,13 +22,10 @@ namespace Microsoft.Bot.Builder.Dialogs
|
|||
{
|
||||
private const string DIALOGS = "_dialogs";
|
||||
private const string LASTACCESS = "_lastAccess";
|
||||
private DialogSet dialogSet;
|
||||
private string rootDialogId;
|
||||
|
||||
public DialogManager(Dialog rootDialog = null)
|
||||
{
|
||||
this.dialogSet = new DialogSet();
|
||||
|
||||
if (rootDialog != null)
|
||||
{
|
||||
this.RootDialog = rootDialog;
|
||||
|
@ -63,7 +60,7 @@ namespace Microsoft.Bot.Builder.Dialogs
|
|||
{
|
||||
if (this.rootDialogId != null)
|
||||
{
|
||||
return this.dialogSet.Find(this.rootDialogId);
|
||||
return this.Dialogs.Find(this.rootDialogId);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
@ -71,11 +68,11 @@ namespace Microsoft.Bot.Builder.Dialogs
|
|||
|
||||
set
|
||||
{
|
||||
this.dialogSet = new DialogSet();
|
||||
this.Dialogs = new DialogSet();
|
||||
if (value != null)
|
||||
{
|
||||
this.rootDialogId = value.Id;
|
||||
this.dialogSet.Add(value);
|
||||
this.Dialogs.Add(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -84,6 +81,13 @@ namespace Microsoft.Bot.Builder.Dialogs
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets global dialogs that you want to have be callable.
|
||||
/// </summary>
|
||||
/// <value>Dialogs set.</value>
|
||||
[JsonIgnore]
|
||||
public DialogSet Dialogs { get; set; } = new DialogSet();
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the DialogStateManagerConfiguration.
|
||||
/// </summary>
|
||||
|
@ -141,7 +145,7 @@ namespace Microsoft.Bot.Builder.Dialogs
|
|||
DialogState dialogState = await dialogsProperty.GetAsync(context, () => new DialogState(), cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
|
||||
// Create DialogContext
|
||||
var dc = new DialogContext(this.dialogSet, context, dialogState);
|
||||
var dc = new DialogContext(this.Dialogs, context, dialogState);
|
||||
|
||||
// set DSM configuration
|
||||
dc.SetStateConfiguration(this.StateConfiguration ?? DialogStateManager.CreateStandardConfiguration(conversationState, userState));
|
||||
|
|
|
@ -46,7 +46,9 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive
|
|||
/// <returns>Event queues.</returns>
|
||||
public static EntityEvents Read(SequenceContext context)
|
||||
{
|
||||
if (!context.GetState().TryGetValue<EntityEvents>(Events, out var queues))
|
||||
var dcState = context.GetState();
|
||||
|
||||
if (!dcState.TryGetValue<EntityEvents>(Events, out var queues))
|
||||
{
|
||||
queues = new EntityEvents();
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
@ -16,8 +17,9 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
/// Ask for an open-ended response.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This sends an activity and then terminates with <see cref="DialogTurnStatus.CompleteAndWait"/> in order to allow the parent
|
||||
/// adaptive dialog to handle the user utterance.
|
||||
/// This sends an activity and then terminates the turn with <see cref="DialogTurnStatus.CompleteAndWait"/>.
|
||||
/// The next activity from the user will then be handled by the parent adaptive dialog.
|
||||
///
|
||||
/// It also builds in a model of the properties that are expected in response through <see cref="DialogPath.ExpectedProperties"/>.
|
||||
/// <see cref="DialogPath.Retries"/> is updated as the same question is asked multiple times.
|
||||
/// </remarks>
|
||||
|
@ -29,7 +31,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
[JsonConstructor]
|
||||
public Ask(
|
||||
string text = null,
|
||||
ExpressionProperty<List<string>> expectedProperties = null,
|
||||
ArrayExpression<string> expectedProperties = null,
|
||||
[CallerFilePath] string callerPath = "",
|
||||
[CallerLineNumber] int callerLine = 0)
|
||||
: base(text, callerPath, callerLine)
|
||||
|
@ -45,24 +47,26 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
/// Properties expected to be filled by response.
|
||||
/// </value>
|
||||
[JsonProperty("expectedProperties")]
|
||||
public ExpressionProperty<List<string>> ExpectedProperties { get; set; }
|
||||
public ArrayExpression<string> ExpectedProperties { get; set; }
|
||||
|
||||
public override async Task<DialogTurnResult> BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var dcState = dc.GetState();
|
||||
|
||||
//get number of retries from memory
|
||||
if (!dc.GetState().TryGetValue(DialogPath.Retries, out int retries))
|
||||
if (!dcState.TryGetValue(DialogPath.Retries, out int retries))
|
||||
{
|
||||
retries = 0;
|
||||
}
|
||||
|
||||
dc.GetState().TryGetValue(TurnPath.DIALOGEVENT, out DialogEvent trigger);
|
||||
dcState.TryGetValue(TurnPath.DIALOGEVENT, out DialogEvent trigger);
|
||||
|
||||
var expected = ExpectedProperties?.GetValue(dc.GetState());
|
||||
var expected = this.ExpectedProperties?.GetValue(dcState);
|
||||
if (expected != null
|
||||
&& dc.GetState().TryGetValue(DialogPath.ExpectedProperties, out List<string> lastExpectedProperties)
|
||||
&& dcState.TryGetValue(DialogPath.ExpectedProperties, out List<string> lastExpectedProperties)
|
||||
&& !expected.Any(prop => !lastExpectedProperties.Contains(prop))
|
||||
&& !lastExpectedProperties.Any(prop => !expected.Contains(prop))
|
||||
&& dc.GetState().TryGetValue(DialogPath.LastTriggerEvent, out DialogEvent lastTrigger)
|
||||
&& dcState.TryGetValue(DialogPath.LastTriggerEvent, out DialogEvent lastTrigger)
|
||||
&& lastTrigger.Name.Equals(trigger.Name))
|
||||
{
|
||||
retries++;
|
||||
|
@ -72,9 +76,9 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
|
|||
retries = 0;
|
||||
}
|
||||
|
||||
dc.GetState().SetValue(DialogPath.Retries, retries);
|
||||
dc.GetState().SetValue(DialogPath.LastTriggerEvent, trigger);
|
||||
dc.GetState().SetValue(DialogPath.ExpectedProperties, expected);
|
||||
dcState.SetValue(DialogPath.Retries, retries);
|
||||
dcState.SetValue(DialogPath.LastTriggerEvent, trigger);
|
||||
dcState.SetValue(DialogPath.ExpectedProperties, expected);
|
||||
var result = await base.BeginDialogAsync(dc, options, cancellationToken).ConfigureAwait(false);
|
||||
result.Status = DialogTurnStatus.CompleteAndWait;
|
||||
return result;
|
||||
|
|
|
@ -38,11 +38,12 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Input
|
|||
}
|
||||
|
||||
[JsonProperty("outputFormat")]
|
||||
public AttachmentOutputFormat OutputFormat { get; set; } = AttachmentOutputFormat.First;
|
||||
public EnumExpression<AttachmentOutputFormat> OutputFormat { get; set; } = AttachmentOutputFormat.First;
|
||||
|
||||
protected override Task<InputState> OnRecognizeInput(DialogContext dc)
|
||||
{
|
||||
var input = dc.GetState().GetValue<List<Attachment>>(VALUE_PROPERTY);
|
||||
var dcState = dc.GetState();
|
||||
var input = dcState.GetValue<List<Attachment>>(VALUE_PROPERTY);
|
||||
var first = input.Count > 0 ? input[0] : null;
|
||||
|
||||
if (first == null || (string.IsNullOrEmpty(first.ContentUrl) && first.Content == null))
|
||||
|
@ -50,13 +51,13 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Input
|
|||
return Task.FromResult(InputState.Unrecognized);
|
||||
}
|
||||
|
||||
switch (this.OutputFormat)
|
||||
switch (this.OutputFormat.GetValue(dcState))
|
||||
{
|
||||
case AttachmentOutputFormat.All:
|
||||
dc.GetState().SetValue(VALUE_PROPERTY, input);
|
||||
dcState.SetValue(VALUE_PROPERTY, input);
|
||||
break;
|
||||
case AttachmentOutputFormat.First:
|
||||
dc.GetState().SetValue(VALUE_PROPERTY, first);
|
||||
dcState.SetValue(VALUE_PROPERTY, first);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -61,7 +61,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Input
|
|||
/// Value Expression or List of choices (string or Choice objects) to present to user.
|
||||
/// </value>
|
||||
[JsonProperty("choices")]
|
||||
public ChoiceSet Choices { get; set; }
|
||||
public ObjectExpression<ChoiceSet> Choices { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets listStyle to use to render the choices.
|
||||
|
@ -70,7 +70,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Input
|
|||
/// ListStyle to use to render the choices.
|
||||
/// </value>
|
||||
[JsonProperty("style")]
|
||||
public ListStyle Style { get; set; } = ListStyle.Auto;
|
||||
public EnumExpression<ListStyle> Style { get; set; } = ListStyle.Auto;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets defaultLocale.
|
||||
|
@ -79,7 +79,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Input
|
|||
/// DefaultLocale.
|
||||
/// </value>
|
||||
[JsonProperty("defaultLocale")]
|
||||
public string DefaultLocale { get; set; } = null;
|
||||
public StringExpression DefaultLocale { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets control the format of the response (value or the index of the choice).
|
||||
|
@ -88,7 +88,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Input
|
|||
/// Control the format of the response (value or the index of the choice).
|
||||
/// </value>
|
||||
[JsonProperty("outputFormat")]
|
||||
public ChoiceOutputFormat OutputFormat { get; set; } = ChoiceOutputFormat.Value;
|
||||
public EnumExpression<ChoiceOutputFormat> OutputFormat { get; set; } = ChoiceOutputFormat.Value;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets choiceOptions controls display options for customizing language.
|
||||
|
@ -97,7 +97,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Input
|
|||
/// ChoiceOptions controls display options for customizing language.
|
||||
/// </value>
|
||||
[JsonProperty("choiceOptions")]
|
||||
public ChoiceFactoryOptions ChoiceOptions { get; set; } = null;
|
||||
public ObjectExpression<ChoiceFactoryOptions> ChoiceOptions { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets customize how to use the choices to recognize the response from the user.
|
||||
|
@ -106,7 +106,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Input
|
|||
/// Customize how to use the choices to recognize the response from the user.
|
||||
/// </value>
|
||||
[JsonProperty("recognizerOptions")]
|
||||
public FindChoicesOptions RecognizerOptions { get; set; } = null;
|
||||
public ObjectExpression<FindChoicesOptions> RecognizerOptions { get; set; } = null;
|
||||
|
||||
public override Task<DialogTurnResult> ResumeDialogAsync(DialogContext dc, DialogReason reason, object result = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
|
@ -125,12 +125,18 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Input
|
|||
var op = options as ChoiceInputOptions;
|
||||
if (op == null || op.Choices == null || op.Choices.Count == 0)
|
||||
{
|
||||
var dcState = dc.GetState();
|
||||
if (op == null)
|
||||
{
|
||||
op = new ChoiceInputOptions();
|
||||
}
|
||||
|
||||
var choices = this.Choices.GetValue(dc.GetState());
|
||||
var (choices, error) = this.Choices.TryGetValue(dcState);
|
||||
if (error != null)
|
||||
{
|
||||
throw new Exception(error);
|
||||
}
|
||||
|
||||
op.Choices = choices;
|
||||
}
|
||||
|
||||
|
@ -139,15 +145,17 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Input
|
|||
|
||||
protected override Task<InputState> OnRecognizeInput(DialogContext dc)
|
||||
{
|
||||
var input = dc.GetState().GetValue<object>(VALUE_PROPERTY);
|
||||
var options = dc.GetState().GetValue<ChoiceInputOptions>(ThisPath.OPTIONS);
|
||||
var dcState = dc.GetState();
|
||||
|
||||
var input = dcState.GetValue<object>(VALUE_PROPERTY);
|
||||
var options = dcState.GetValue<ChoiceInputOptions>(ThisPath.OPTIONS);
|
||||
|
||||
var choices = options.Choices;
|
||||
|
||||
var result = new PromptRecognizerResult<FoundChoice>();
|
||||
if (dc.Context.Activity.Type == ActivityTypes.Message)
|
||||
{
|
||||
var opt = this.RecognizerOptions ?? new FindChoicesOptions();
|
||||
var opt = this.RecognizerOptions?.GetValue(dcState) ?? new FindChoicesOptions();
|
||||
opt.Locale = GetCulture(dc);
|
||||
var results = ChoiceRecognizers.RecognizeChoices(input.ToString(), choices, opt);
|
||||
if (results == null || results.Count == 0)
|
||||
|
@ -156,14 +164,14 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Input
|
|||
}
|
||||
|
||||
var foundChoice = results[0].Resolution;
|
||||
switch (this.OutputFormat)
|
||||
switch (this.OutputFormat.GetValue(dcState))
|
||||
{
|
||||
case ChoiceOutputFormat.Value:
|
||||
default:
|
||||
dc.GetState().SetValue(VALUE_PROPERTY, foundChoice.Value);
|
||||
dcState.SetValue(VALUE_PROPERTY, foundChoice.Value);
|
||||
break;
|
||||
case ChoiceOutputFormat.Index:
|
||||
dc.GetState().SetValue(VALUE_PROPERTY, foundChoice.Index);
|
||||
dcState.SetValue(VALUE_PROPERTY, foundChoice.Index);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -173,27 +181,34 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Input
|
|||
|
||||
protected override async Task<IActivity> OnRenderPrompt(DialogContext dc, InputState state)
|
||||
{
|
||||
var dcState = dc.GetState();
|
||||
var locale = GetCulture(dc);
|
||||
var prompt = await base.OnRenderPrompt(dc, state);
|
||||
var channelId = dc.Context.Activity.ChannelId;
|
||||
var choicePrompt = new ChoicePrompt(this.Id);
|
||||
var choiceOptions = this.ChoiceOptions ?? ChoiceInput.DefaultChoiceOptions[locale];
|
||||
var choiceOptions = this.ChoiceOptions?.GetValue(dcState) ?? ChoiceInput.DefaultChoiceOptions[locale];
|
||||
|
||||
var choices = this.Choices.GetValue(dc.GetState());
|
||||
var (choices, error) = this.Choices.TryGetValue(dcState);
|
||||
if (error != null)
|
||||
{
|
||||
throw new Exception(error);
|
||||
}
|
||||
|
||||
return this.AppendChoices(prompt.AsMessageActivity(), channelId, choices, this.Style, choiceOptions);
|
||||
return this.AppendChoices(prompt.AsMessageActivity(), channelId, choices, this.Style.GetValue(dcState), choiceOptions);
|
||||
}
|
||||
|
||||
private string GetCulture(DialogContext dc)
|
||||
{
|
||||
var dcState = dc.GetState();
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(dc.Context.Activity.Locale))
|
||||
{
|
||||
return dc.Context.Activity.Locale;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(this.DefaultLocale))
|
||||
if (this.DefaultLocale != null)
|
||||
{
|
||||
return this.DefaultLocale;
|
||||
return this.DefaultLocale.GetValue(dcState);
|
||||
}
|
||||
|
||||
return English;
|
||||
|
|
|
@ -1,69 +1,60 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Bot.Builder.Dialogs.Choices;
|
||||
using Microsoft.Bot.Builder.Dialogs.Declarative;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Microsoft.Bot.Builder.Dialogs.Adaptive
|
||||
namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Input
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines Choices Property as either collection of Choices, array of strings or string which is an expression to one of thoses.
|
||||
/// Defines ChoiceSet collection.
|
||||
/// </summary>
|
||||
public class ChoiceSet : ExpressionProperty<List<Choice>>
|
||||
[JsonConverter(typeof(ChoiceSetConverter))]
|
||||
public class ChoiceSet : List<Choice>
|
||||
{
|
||||
public ChoiceSet()
|
||||
{
|
||||
}
|
||||
|
||||
public ChoiceSet(string expression)
|
||||
: base(expression)
|
||||
{
|
||||
}
|
||||
|
||||
public ChoiceSet(List<Choice> choices)
|
||||
public ChoiceSet(IEnumerable<Choice> choices)
|
||||
: base(choices)
|
||||
{
|
||||
}
|
||||
|
||||
public ChoiceSet(object choices)
|
||||
: base(choices)
|
||||
{
|
||||
}
|
||||
|
||||
protected override List<Choice> ConvertObject(object result)
|
||||
public ChoiceSet(object obj)
|
||||
{
|
||||
// support string[] => choice[]
|
||||
if (result is IEnumerable<string> strings)
|
||||
if (obj is IEnumerable<string> strings)
|
||||
{
|
||||
return strings.Select(s => new Choice(s)).ToList();
|
||||
foreach (var str in strings)
|
||||
{
|
||||
this.Add(new Choice(str));
|
||||
}
|
||||
}
|
||||
|
||||
// support JArray to => choice
|
||||
if (result is JArray array)
|
||||
if (obj is JArray array)
|
||||
{
|
||||
var choices = new List<Choice>();
|
||||
if (array.HasValues)
|
||||
{
|
||||
foreach (var element in array)
|
||||
{
|
||||
if (element is JValue jval)
|
||||
{
|
||||
choices.Add(new Choice(element.ToString()));
|
||||
this.Add(new Choice(element.ToString()));
|
||||
}
|
||||
else if (element is JObject jobj)
|
||||
{
|
||||
choices.Add(jobj.ToObject<Choice>());
|
||||
this.Add(jobj.ToObject<Choice>());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return choices;
|
||||
}
|
||||
public static implicit operator ChoiceSet(bool value) => new ChoiceSet(value);
|
||||
|
||||
return JArray.FromObject(result).ToObject<List<Choice>>();
|
||||
}
|
||||
public static implicit operator ChoiceSet(string value) => new ChoiceSet(value);
|
||||
|
||||
public static implicit operator ChoiceSet(JToken value) => new ChoiceSet(value);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ using System.Collections.Generic;
|
|||
using System.Runtime.CompilerServices;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Bot.Builder.Dialogs.Choices;
|
||||
using Microsoft.Bot.Builder.Dialogs.Declarative;
|
||||
using Microsoft.Bot.Expressions;
|
||||
using Microsoft.Bot.Schema;
|
||||
using Microsoft.Recognizers.Text.Choice;
|
||||
|
@ -40,23 +41,24 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Input
|
|||
}
|
||||
|
||||
[JsonProperty("defaultLocale")]
|
||||
public string DefaultLocale { get; set; } = null;
|
||||
public StringExpression DefaultLocale { get; set; }
|
||||
|
||||
[JsonProperty("style")]
|
||||
public ListStyle Style { get; set; } = ListStyle.Auto;
|
||||
public EnumExpression<ListStyle> Style { get; set; } = ListStyle.Auto;
|
||||
|
||||
[JsonProperty("choiceOptions")]
|
||||
public ChoiceFactoryOptions ChoiceOptions { get; set; } = null;
|
||||
public ObjectExpression<ChoiceFactoryOptions> ChoiceOptions { get; set; }
|
||||
|
||||
[JsonProperty("confirmChoices")]
|
||||
public List<Choice> ConfirmChoices { get; set; } = null;
|
||||
public ArrayExpression<Choice> ConfirmChoices { get; set; }
|
||||
|
||||
[JsonProperty("outputFormat")]
|
||||
public string OutputFormat { get; set; }
|
||||
public StringExpression OutputFormat { get; set; }
|
||||
|
||||
protected override Task<InputState> OnRecognizeInput(DialogContext dc)
|
||||
{
|
||||
var input = dc.GetState().GetValue<object>(VALUE_PROPERTY);
|
||||
var dcState = dc.GetState();
|
||||
var input = dcState.GetValue<object>(VALUE_PROPERTY);
|
||||
if (dc.Context.Activity.Type == ActivityTypes.Message)
|
||||
{
|
||||
// Recognize utterance
|
||||
|
@ -67,18 +69,17 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Input
|
|||
var first = results[0];
|
||||
if (bool.TryParse(first.Resolution["value"].ToString(), out var value))
|
||||
{
|
||||
dc.GetState().SetValue(VALUE_PROPERTY, value);
|
||||
if (!string.IsNullOrEmpty(OutputFormat))
|
||||
dcState.SetValue(VALUE_PROPERTY, value);
|
||||
if (OutputFormat != null)
|
||||
{
|
||||
var outputExpression = new ExpressionEngine().Parse(OutputFormat);
|
||||
var (outputValue, error) = outputExpression.TryEvaluate(dc.GetState());
|
||||
var (outputValue, error) = OutputFormat.TryGetValue(dcState);
|
||||
if (error == null)
|
||||
{
|
||||
dc.GetState().SetValue(VALUE_PROPERTY, outputValue);
|
||||
dcState.SetValue(VALUE_PROPERTY, outputValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception($"OutputFormat Expression evaluation resulted in an error. Expression: {outputExpression.ToString()}. Error: {error}");
|
||||
throw new Exception($"OutputFormat Expression evaluation resulted in an error. Expression: {OutputFormat.ToString()}. Error: {error}");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -93,18 +94,18 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Input
|
|||
{
|
||||
// First check whether the prompt was sent to the user with numbers - if it was we should recognize numbers
|
||||
var defaults = ChoiceDefaults[culture];
|
||||
var choiceOptions = ChoiceOptions ?? defaults.Item3;
|
||||
var choiceOptions = ChoiceOptions?.GetValue(dcState) ?? defaults.Item3;
|
||||
|
||||
// This logic reflects the fact that IncludeNumbers is nullable and True is the default set in Inline style
|
||||
if (!choiceOptions.IncludeNumbers.HasValue || choiceOptions.IncludeNumbers.Value)
|
||||
{
|
||||
// The text may be a number in which case we will interpret that as a choice.
|
||||
var confirmChoices = ConfirmChoices ?? new List<Choice>() { defaults.Item1, defaults.Item2 };
|
||||
var confirmChoices = ConfirmChoices?.GetValue(dcState) ?? new List<Choice>() { defaults.Item1, defaults.Item2 };
|
||||
var secondAttemptResults = ChoiceRecognizers.RecognizeChoices(input.ToString(), confirmChoices);
|
||||
if (secondAttemptResults.Count > 0)
|
||||
{
|
||||
input = secondAttemptResults[0].Resolution.Index == 0;
|
||||
dc.GetState().SetValue(VALUE_PROPERTY, input);
|
||||
dcState.SetValue(VALUE_PROPERTY, input);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -120,15 +121,16 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Input
|
|||
protected override async Task<IActivity> OnRenderPrompt(DialogContext dc, InputState state)
|
||||
{
|
||||
// Format prompt to send
|
||||
var dcState = dc.GetState();
|
||||
var channelId = dc.Context.Activity.ChannelId;
|
||||
var culture = GetCulture(dc);
|
||||
var defaults = ChoiceDefaults[culture];
|
||||
var choiceOptions = ChoiceOptions ?? defaults.Item3;
|
||||
var confirmChoices = ConfirmChoices ?? new List<Choice>() { defaults.Item1, defaults.Item2 };
|
||||
var choiceOptions = ChoiceOptions?.GetValue(dcState) ?? defaults.Item3;
|
||||
var confirmChoices = ConfirmChoices?.GetValue(dcState) ?? new List<Choice>() { defaults.Item1, defaults.Item2 };
|
||||
|
||||
var prompt = await base.OnRenderPrompt(dc, state);
|
||||
|
||||
return this.AppendChoices(prompt.AsMessageActivity(), channelId, confirmChoices, this.Style, choiceOptions);
|
||||
var (style, error) = this.Style.TryGetValue(dcState);
|
||||
return this.AppendChoices(prompt.AsMessageActivity(), channelId, confirmChoices, style, choiceOptions);
|
||||
}
|
||||
|
||||
private string GetCulture(DialogContext dc)
|
||||
|
@ -138,9 +140,10 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Input
|
|||
return dc.Context.Activity.Locale;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(this.DefaultLocale))
|
||||
if (this.DefaultLocale != null)
|
||||
{
|
||||
return this.DefaultLocale;
|
||||
var dcState = dc.GetState();
|
||||
return this.DefaultLocale.GetValue(dcState);
|
||||
}
|
||||
|
||||
return English;
|
||||
|
|
|
@ -23,17 +23,18 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Input
|
|||
}
|
||||
|
||||
[JsonProperty("defaultLocale")]
|
||||
public string DefaultLocale { get; set; } = null;
|
||||
public StringExpression DefaultLocale { get; set; } = null;
|
||||
|
||||
[JsonProperty("outputFormat")]
|
||||
public string OutputFormat { get; set; }
|
||||
public StringExpression OutputFormat { get; set; }
|
||||
|
||||
protected override Task<InputState> OnRecognizeInput(DialogContext dc)
|
||||
{
|
||||
var input = dc.GetState().GetValue<object>(VALUE_PROPERTY);
|
||||
|
||||
var dcState = dc.GetState();
|
||||
var input = dcState.GetValue<object>(VALUE_PROPERTY);
|
||||
var culture = GetCulture(dc);
|
||||
var results = DateTimeRecognizer.RecognizeDateTime(input.ToString(), culture);
|
||||
var refTime = dc.Context.Activity.LocalTimestamp?.LocalDateTime;
|
||||
var results = DateTimeRecognizer.RecognizeDateTime(input.ToString(), culture, refTime: refTime);
|
||||
if (results.Count > 0)
|
||||
{
|
||||
// Return list of resolutions from first match
|
||||
|
@ -44,18 +45,18 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Input
|
|||
result.Add(ReadResolution(value));
|
||||
}
|
||||
|
||||
dc.GetState().SetValue(VALUE_PROPERTY, result);
|
||||
if (!string.IsNullOrEmpty(OutputFormat))
|
||||
dcState.SetValue(VALUE_PROPERTY, result);
|
||||
|
||||
if (OutputFormat != null)
|
||||
{
|
||||
var outputExpression = new ExpressionEngine().Parse(OutputFormat);
|
||||
var (outputValue, error) = outputExpression.TryEvaluate(dc.GetState());
|
||||
var (outputValue, error) = this.OutputFormat.TryGetValue(dcState);
|
||||
if (error == null)
|
||||
{
|
||||
dc.GetState().SetValue(VALUE_PROPERTY, outputValue);
|
||||
dcState.SetValue(VALUE_PROPERTY, outputValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception($"OutputFormat Expression evaluation resulted in an error. Expression: {outputExpression.ToString()}. Error: {error}");
|
||||
throw new Exception($"OutputFormat Expression evaluation resulted in an error. Expression: {this.OutputFormat}. Error: {error}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -101,9 +102,10 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Input
|
|||
return dc.Context.Activity.Locale;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(this.DefaultLocale))
|
||||
if (this.DefaultLocale != null)
|
||||
{
|
||||
return this.DefaultLocale;
|
||||
var dcState = dc.GetState();
|
||||
return this.DefaultLocale.GetValue(dcState);
|
||||
}
|
||||
|
||||
return English;
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
@ -21,9 +22,6 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Input
|
|||
protected const string VALUE_PROPERTY = "this.value";
|
||||
#pragma warning restore SA1310 // Field should not contain underscore.
|
||||
|
||||
private Expression allowInterruptions;
|
||||
private Expression disabled;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether the input should always prompt the user regardless of there being a value or not.
|
||||
/// </summary>
|
||||
|
@ -31,7 +29,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Input
|
|||
/// A value indicating whether the input should always prompt the user regardless of there being a value or not.
|
||||
/// </value>
|
||||
[JsonProperty("alwaysPrompt")]
|
||||
public bool AlwaysPrompt { get; set; } = false;
|
||||
public BoolExpression AlwaysPrompt { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets intteruption policy.
|
||||
|
@ -40,14 +38,10 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Input
|
|||
/// "true".
|
||||
/// </example>
|
||||
/// <value>
|
||||
/// Intteruption policy.
|
||||
/// Intteruption policy. Default is True.
|
||||
/// </value>
|
||||
[JsonProperty("allowInterruptions")]
|
||||
public string AllowInterruptions
|
||||
{
|
||||
get { return allowInterruptions?.ToString(); }
|
||||
set { allowInterruptions = value != null ? new ExpressionEngine().Parse(value) : null; }
|
||||
}
|
||||
public BoolExpression AllowInterruptions { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets an optional expression which if is true will disable this action.
|
||||
|
@ -56,23 +50,19 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Input
|
|||
/// "user.age > 18".
|
||||
/// </example>
|
||||
/// <value>
|
||||
/// A boolean expression.
|
||||
/// A boolean expression. Default is false.
|
||||
/// </value>
|
||||
[JsonProperty("disabled")]
|
||||
public string Disabled
|
||||
{
|
||||
get { return disabled?.ToString(); }
|
||||
set { disabled = value != null ? new ExpressionEngine().Parse(value) : null; }
|
||||
}
|
||||
public BoolExpression Disabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the value expression which the input will be bound to.
|
||||
/// Gets or sets the memory property path which the value will be bound to.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The value expression which the input will be bound to.
|
||||
/// The property path to the value that the input dialog will be bound to.
|
||||
/// </value>
|
||||
[JsonProperty("property")]
|
||||
public string Property { get; set; }
|
||||
public StringExpression Property { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value expression which can be used to intialize the input prompt.
|
||||
|
@ -85,7 +75,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Input
|
|||
/// A value expression which can be used to intialize the input prompt.
|
||||
/// </value>
|
||||
[JsonProperty("value")]
|
||||
public string Value { get; set; }
|
||||
public ValueExpression Value { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the activity to send to the user.
|
||||
|
@ -133,13 +123,13 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Input
|
|||
public List<string> Validations { get; set; } = new List<string>();
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets maximum number of times to ask the user for this value before the dilog gives up.
|
||||
/// Gets or sets maximum number of times to ask the user for this value before the dialog gives up.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// Maximum number of times to ask the user for this value before the dilog gives up.
|
||||
/// </value>
|
||||
[JsonProperty("maxTurnCount")]
|
||||
public int? MaxTurnCount { get; set; }
|
||||
public IntExpression MaxTurnCount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the default value for the input dialog when MaxTurnCount is exceeded.
|
||||
|
@ -148,7 +138,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Input
|
|||
/// The default value for the input dialog when MaxTurnCount is exceeded.
|
||||
/// </value>
|
||||
[JsonProperty("defaultValue")]
|
||||
public string DefaultValue { get; set; }
|
||||
public ValueExpression DefaultValue { get; set; }
|
||||
|
||||
public override async Task<DialogTurnResult> BeginDialogAsync(DialogContext dc, object options, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
|
@ -162,28 +152,33 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Input
|
|||
throw new ArgumentException($"{nameof(options)} cannot be a cancellation token");
|
||||
}
|
||||
|
||||
if (this.disabled != null && (bool?)this.disabled.TryEvaluate(dc.GetState()).value == true)
|
||||
var dcState = dc.GetState();
|
||||
|
||||
if (this.Disabled != null && this.Disabled.GetValue(dcState) == true)
|
||||
{
|
||||
return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
var op = OnInitializeOptions(dc, options);
|
||||
dc.GetState().SetValue(ThisPath.OPTIONS, op);
|
||||
dc.GetState().SetValue(TURN_COUNT_PROPERTY, 0);
|
||||
dcState.SetValue(ThisPath.OPTIONS, op);
|
||||
dcState.SetValue(TURN_COUNT_PROPERTY, 0);
|
||||
|
||||
var alwaysPrompt = this.AlwaysPrompt?.GetValue(dcState) ?? false;
|
||||
|
||||
// If AlwaysPrompt is set to true, then clear Property value for turn 0.
|
||||
if (!string.IsNullOrEmpty(this.Property) && this.AlwaysPrompt)
|
||||
var property = this.Property?.GetValue(dcState);
|
||||
if (property != null && alwaysPrompt)
|
||||
{
|
||||
dc.GetState().SetValue(this.Property, null);
|
||||
dcState.SetValue(property, null);
|
||||
}
|
||||
|
||||
var state = this.AlwaysPrompt ? InputState.Missing : await this.RecognizeInput(dc, 0);
|
||||
var state = alwaysPrompt ? InputState.Missing : await this.RecognizeInput(dc, 0);
|
||||
if (state == InputState.Valid)
|
||||
{
|
||||
var input = dc.GetState().GetValue<object>(VALUE_PROPERTY);
|
||||
var input = dcState.GetValue<object>(VALUE_PROPERTY);
|
||||
|
||||
// set property
|
||||
dc.GetState().SetValue(this.Property, input);
|
||||
dcState.SetValue(property, input);
|
||||
|
||||
// return as result too
|
||||
return await dc.EndDialogAsync(input);
|
||||
|
@ -193,7 +188,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Input
|
|||
// turnCount should increase here, because you want when nextTurn comes in
|
||||
// We will set the turn count to 1 so the input will not pick from "dialog.value"
|
||||
// and instead go with "turn.activity.text"
|
||||
dc.GetState().SetValue(TURN_COUNT_PROPERTY, 1);
|
||||
dcState.SetValue(TURN_COUNT_PROPERTY, 1);
|
||||
return await this.PromptUser(dc, state);
|
||||
}
|
||||
}
|
||||
|
@ -206,43 +201,45 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Input
|
|||
return Dialog.EndOfTurn;
|
||||
}
|
||||
|
||||
var interrupted = dc.GetState().GetValue<bool>(TurnPath.INTERRUPTED, () => false);
|
||||
var turnCount = dc.GetState().GetValue<int>(TURN_COUNT_PROPERTY, () => 0);
|
||||
var dcState = dc.GetState();
|
||||
|
||||
var interrupted = dcState.GetValue<bool>(TurnPath.INTERRUPTED, () => false);
|
||||
var turnCount = dcState.GetValue<int>(TURN_COUNT_PROPERTY, () => 0);
|
||||
|
||||
// Perform base recognition
|
||||
var state = await this.RecognizeInput(dc, interrupted ? 0 : turnCount);
|
||||
|
||||
if (state == InputState.Valid)
|
||||
{
|
||||
var input = dc.GetState().GetValue<object>(VALUE_PROPERTY);
|
||||
var input = dcState.GetValue<object>(VALUE_PROPERTY);
|
||||
|
||||
// set output property
|
||||
if (!string.IsNullOrEmpty(this.Property))
|
||||
if (this.Property != null)
|
||||
{
|
||||
dc.GetState().SetValue(this.Property, input);
|
||||
dcState.SetValue(this.Property.GetValue(dcState), input);
|
||||
}
|
||||
|
||||
return await dc.EndDialogAsync(input).ConfigureAwait(false);
|
||||
}
|
||||
else if (this.MaxTurnCount == null || turnCount < this.MaxTurnCount)
|
||||
else if (this.MaxTurnCount == null || turnCount < this.MaxTurnCount.GetValue(dcState))
|
||||
{
|
||||
// increase the turnCount as last step
|
||||
dc.GetState().SetValue(TURN_COUNT_PROPERTY, turnCount + 1);
|
||||
dcState.SetValue(TURN_COUNT_PROPERTY, turnCount + 1);
|
||||
return await this.PromptUser(dc, state).ConfigureAwait(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (this.DefaultValue != null)
|
||||
{
|
||||
var (value, error) = new ExpressionEngine().Parse(this.DefaultValue).TryEvaluate(dc.GetState());
|
||||
var (value, error) = this.DefaultValue.TryGetValue(dcState);
|
||||
if (this.DefaultValueResponse != null)
|
||||
{
|
||||
var response = await this.DefaultValueResponse.BindToData(dc.Context, dc.GetState()).ConfigureAwait(false);
|
||||
var response = await this.DefaultValueResponse.BindToData(dc.Context, dcState).ConfigureAwait(false);
|
||||
await dc.Context.SendActivityAsync(response).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
// set output property
|
||||
dc.GetState().SetValue(this.Property, value);
|
||||
dcState.SetValue(this.Property.GetValue(dcState), value);
|
||||
|
||||
return await dc.EndDialogAsync(value).ConfigureAwait(false);
|
||||
}
|
||||
|
@ -262,15 +259,17 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Input
|
|||
{
|
||||
if (e.Name == DialogEvents.ActivityReceived && dc.Context.Activity.Type == ActivityTypes.Message)
|
||||
{
|
||||
var dcState = dc.GetState();
|
||||
|
||||
// Ask parent to perform recognition
|
||||
await dc.Parent.EmitEventAsync(AdaptiveEvents.RecognizeUtterance, value: dc.Context.Activity, bubble: false, cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
|
||||
// Should we allow interruptions
|
||||
var canInterrupt = true;
|
||||
if (allowInterruptions != null)
|
||||
if (this.AllowInterruptions != null)
|
||||
{
|
||||
var (value, error) = allowInterruptions.TryEvaluate(dc.GetState());
|
||||
canInterrupt = error == null && value != null && (bool)value;
|
||||
var (allowInterruptions, error) = this.AllowInterruptions.TryGetValue(dcState);
|
||||
canInterrupt = error == null && allowInterruptions;
|
||||
}
|
||||
|
||||
// Stop bubbling if interruptions ar NOT allowed
|
||||
|
@ -349,16 +348,18 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Input
|
|||
|
||||
protected virtual async Task<IActivity> OnRenderPrompt(DialogContext dc, InputState state)
|
||||
{
|
||||
var dcState = dc.GetState();
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case InputState.Unrecognized:
|
||||
if (this.UnrecognizedPrompt != null)
|
||||
{
|
||||
return await this.UnrecognizedPrompt.BindToData(dc.Context, dc.GetState()).ConfigureAwait(false);
|
||||
return await this.UnrecognizedPrompt.BindToData(dc.Context, dcState).ConfigureAwait(false);
|
||||
}
|
||||
else if (this.InvalidPrompt != null)
|
||||
{
|
||||
return await this.InvalidPrompt.BindToData(dc.Context, dc.GetState()).ConfigureAwait(false);
|
||||
return await this.InvalidPrompt.BindToData(dc.Context, dcState).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -366,37 +367,40 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Input
|
|||
case InputState.Invalid:
|
||||
if (this.InvalidPrompt != null)
|
||||
{
|
||||
return await this.InvalidPrompt.BindToData(dc.Context, dc.GetState()).ConfigureAwait(false);
|
||||
return await this.InvalidPrompt.BindToData(dc.Context, dcState).ConfigureAwait(false);
|
||||
}
|
||||
else if (this.UnrecognizedPrompt != null)
|
||||
{
|
||||
return await this.UnrecognizedPrompt.BindToData(dc.Context, dc.GetState()).ConfigureAwait(false);
|
||||
return await this.UnrecognizedPrompt.BindToData(dc.Context, dcState).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return await this.Prompt.BindToData(dc.Context, dc.GetState()).ConfigureAwait(false);
|
||||
return await this.Prompt.BindToData(dc.Context, dcState).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private async Task<InputState> RecognizeInput(DialogContext dc, int turnCount)
|
||||
{
|
||||
dynamic input = null;
|
||||
|
||||
var dcState = dc.GetState();
|
||||
|
||||
// Use Property expression for input first
|
||||
if (!string.IsNullOrEmpty(this.Property))
|
||||
if (this.Property != null)
|
||||
{
|
||||
dc.GetState().TryGetValue(this.Property, out input);
|
||||
var property = this.Property.GetValue(dcState);
|
||||
dcState.TryGetValue(property, out input);
|
||||
|
||||
// Clear property to avoid it being stuck on the next turn. It will get written
|
||||
// back if the value passes validations.
|
||||
dc.GetState().SetValue(this.Property, null);
|
||||
dcState.SetValue(property, null);
|
||||
}
|
||||
|
||||
// Use Value expression for input second
|
||||
if (input == null && !string.IsNullOrEmpty(this.Value))
|
||||
if (input == null && this.Value != null)
|
||||
{
|
||||
var (value, valueError) = new ExpressionEngine().Parse(this.Value).TryEvaluate(dc.GetState());
|
||||
var (value, valueError) = this.Value.TryGetValue(dcState);
|
||||
if (valueError != null)
|
||||
{
|
||||
throw new Exception($"In InputDialog, this.Value expression evaluation resulted in an error. Expression: {this.Value}. Error: {valueError}");
|
||||
|
@ -406,7 +410,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Input
|
|||
}
|
||||
|
||||
// Fallback to using activity
|
||||
bool activityProcessed = dc.GetState().GetBoolValue(TurnPath.ACTIVITYPROCESSED);
|
||||
bool activityProcessed = dcState.GetBoolValue(TurnPath.ACTIVITYPROCESSED);
|
||||
if (!activityProcessed && input == null && turnCount > 0)
|
||||
{
|
||||
if (this.GetType().Name == nameof(AttachmentInput))
|
||||
|
@ -420,7 +424,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Input
|
|||
}
|
||||
|
||||
// Update "this.value" and perform additional recognition and validations
|
||||
dc.GetState().SetValue(VALUE_PROPERTY, input);
|
||||
dcState.SetValue(VALUE_PROPERTY, input);
|
||||
if (input != null)
|
||||
{
|
||||
var state = await this.OnRecognizeInput(dc).ConfigureAwait(false);
|
||||
|
@ -428,15 +432,15 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Input
|
|||
{
|
||||
foreach (var validation in this.Validations)
|
||||
{
|
||||
var exp = new ExpressionEngine().Parse(validation);
|
||||
var (value, error) = exp.TryEvaluate(dc.GetState());
|
||||
var exp = new ExpressionEngine().Parse(validation.TrimStart('='));
|
||||
var (value, error) = exp.TryEvaluate(dcState);
|
||||
if (value == null || (value is bool && (bool)value == false))
|
||||
{
|
||||
return InputState.Invalid;
|
||||
}
|
||||
}
|
||||
|
||||
dc.GetState().SetValue(TurnPath.ACTIVITYPROCESSED, true);
|
||||
dcState.SetValue(TurnPath.ACTIVITYPROCESSED, true);
|
||||
return InputState.Valid;
|
||||
}
|
||||
else
|
||||
|
|
|
@ -23,14 +23,15 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Input
|
|||
}
|
||||
|
||||
[JsonProperty("defaultLocale")]
|
||||
public string DefaultLocale { get; set; } = null;
|
||||
public StringExpression DefaultLocale { get; set; } = null;
|
||||
|
||||
[JsonProperty("outputFormat")]
|
||||
public string OutputFormat { get; set; }
|
||||
public NumberExpression OutputFormat { get; set; }
|
||||
|
||||
protected override Task<InputState> OnRecognizeInput(DialogContext dc)
|
||||
{
|
||||
var input = dc.GetState().GetValue<object>(VALUE_PROPERTY);
|
||||
var dcState = dc.GetState();
|
||||
var input = dcState.GetValue<object>(VALUE_PROPERTY);
|
||||
|
||||
var culture = GetCulture(dc);
|
||||
var results = NumberRecognizer.RecognizeNumber(input.ToString(), culture);
|
||||
|
@ -60,19 +61,18 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Input
|
|||
return Task.FromResult(InputState.Unrecognized);
|
||||
}
|
||||
|
||||
dc.GetState().SetValue(VALUE_PROPERTY, input);
|
||||
dcState.SetValue(VALUE_PROPERTY, input);
|
||||
|
||||
if (!string.IsNullOrEmpty(OutputFormat))
|
||||
if (OutputFormat != null)
|
||||
{
|
||||
var outputExpression = new ExpressionEngine().Parse(OutputFormat);
|
||||
var (outputValue, error) = outputExpression.TryEvaluate(dc.GetState());
|
||||
var (outputValue, error) = this.OutputFormat.TryGetValue(dcState);
|
||||
if (error == null)
|
||||
{
|
||||
dc.GetState().SetValue(VALUE_PROPERTY, outputValue);
|
||||
dcState.SetValue(VALUE_PROPERTY, outputValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception($"In TextInput, OutputFormat Expression evaluation resulted in an error. Expression: {outputExpression.ToString()}. Error: {error}");
|
||||
throw new Exception($"In TextInput, OutputFormat Expression evaluation resulted in an error. Expression: {this.OutputFormat}. Error: {error}");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -86,9 +86,11 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Input
|
|||
return dc.Context.Activity.Locale;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(this.DefaultLocale))
|
||||
if (this.DefaultLocale != null)
|
||||
{
|
||||
return this.DefaultLocale;
|
||||
var dcState = dc.GetState();
|
||||
|
||||
return this.DefaultLocale.GetValue(dcState);
|
||||
}
|
||||
|
||||
return English;
|
||||
|
|
|
@ -34,21 +34,21 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Input
|
|||
/// </summary>
|
||||
/// <value>The name of the OAuth connection.</value>
|
||||
[JsonProperty("connectionName")]
|
||||
public string ConnectionName { get; set; }
|
||||
public StringExpression ConnectionName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the title of the sign-in card.
|
||||
/// </summary>
|
||||
/// <value>The title of the sign-in card.</value>
|
||||
[JsonProperty("title")]
|
||||
public string Title { get; set; }
|
||||
public StringExpression Title { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets any additional text to include in the sign-in card.
|
||||
/// </summary>
|
||||
/// <value>Any additional text to include in the sign-in card.</value>
|
||||
[JsonProperty("text")]
|
||||
public string Text { get; set; }
|
||||
public StringExpression Text { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the number of milliseconds the prompt waits for the user to authenticate.
|
||||
|
@ -56,7 +56,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Input
|
|||
/// </summary>
|
||||
/// <value>The number of milliseconds the prompt waits for the user to authenticate.</value>
|
||||
[JsonProperty("timeout")]
|
||||
public int Timeout { get; set; } = 900000;
|
||||
public IntExpression Timeout { get; set; } = 900000;
|
||||
|
||||
/// <summary>
|
||||
/// Called when a prompt dialog is pushed onto the dialog stack and is being activated.
|
||||
|
@ -80,7 +80,9 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Input
|
|||
throw new ArgumentException($"{nameof(options)} cannot be a cancellation token");
|
||||
}
|
||||
|
||||
if (this.Disabled != null && (bool)new ExpressionEngine().Parse(this.Disabled).TryEvaluate(dc.GetState()).value == true)
|
||||
var dcState = dc.GetState();
|
||||
|
||||
if (this.Disabled != null && this.Disabled.GetValue(dcState))
|
||||
{
|
||||
return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
@ -105,13 +107,15 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Input
|
|||
}
|
||||
|
||||
var op = OnInitializeOptions(dc, options);
|
||||
dc.GetState().SetValue(ThisPath.OPTIONS, op);
|
||||
dc.GetState().SetValue(TURN_COUNT_PROPERTY, 0);
|
||||
dcState.SetValue(ThisPath.OPTIONS, op);
|
||||
dcState.SetValue(TURN_COUNT_PROPERTY, 0);
|
||||
|
||||
// If AlwaysPrompt is set to true, then clear Property value for turn 0.
|
||||
if (!string.IsNullOrEmpty(this.Property) && this.AlwaysPrompt)
|
||||
var (alwaysPrompt, _) = this.AlwaysPrompt.TryGetValue(dcState);
|
||||
|
||||
if (this.Property != null && alwaysPrompt)
|
||||
{
|
||||
dc.GetState().SetValue(this.Property, null);
|
||||
dcState.SetValue(this.Property.GetValue(dcState), null);
|
||||
}
|
||||
|
||||
// Initialize state
|
||||
|
@ -122,7 +126,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Input
|
|||
{ AttemptCountKey, 0 },
|
||||
};
|
||||
|
||||
state[PersistedExpires] = DateTime.Now.AddMilliseconds(Timeout);
|
||||
state[PersistedExpires] = DateTime.Now.AddMilliseconds(Timeout.GetValue(dcState));
|
||||
|
||||
// Attempt to get the users token
|
||||
if (!(dc.Context.Adapter is IUserTokenProvider adapter))
|
||||
|
@ -130,12 +134,12 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Input
|
|||
throw new InvalidOperationException("OAuthPrompt.Recognize(): not supported by the current adapter");
|
||||
}
|
||||
|
||||
var output = await adapter.GetUserTokenAsync(dc.Context, ConnectionName, null, cancellationToken).ConfigureAwait(false);
|
||||
var output = await adapter.GetUserTokenAsync(dc.Context, ConnectionName.GetValue(dcState), null, cancellationToken).ConfigureAwait(false);
|
||||
if (output != null)
|
||||
{
|
||||
if (this.Property != null)
|
||||
{
|
||||
dc.GetState().SetValue(this.Property, output);
|
||||
dcState.SetValue(this.Property.GetValue(dcState), output);
|
||||
}
|
||||
|
||||
// Return token
|
||||
|
@ -143,10 +147,10 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Input
|
|||
}
|
||||
else
|
||||
{
|
||||
dc.GetState().SetValue(TURN_COUNT_PROPERTY, 1);
|
||||
dcState.SetValue(TURN_COUNT_PROPERTY, 1);
|
||||
|
||||
// Prompt user to login
|
||||
await SendOAuthCardAsync(dc.Context, opt?.Prompt, cancellationToken).ConfigureAwait(false);
|
||||
await SendOAuthCardAsync(dc, opt?.Prompt, cancellationToken).ConfigureAwait(false);
|
||||
return Dialog.EndOfTurn;
|
||||
}
|
||||
}
|
||||
|
@ -169,11 +173,12 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Input
|
|||
throw new ArgumentNullException(nameof(dc));
|
||||
}
|
||||
|
||||
var interrupted = dc.GetState().GetValue<bool>(TurnPath.INTERRUPTED, () => false);
|
||||
var turnCount = dc.GetState().GetValue<int>(TURN_COUNT_PROPERTY, () => 0);
|
||||
var dcState = dc.GetState();
|
||||
var interrupted = dcState.GetValue<bool>(TurnPath.INTERRUPTED, () => false);
|
||||
var turnCount = dcState.GetValue<int>(TURN_COUNT_PROPERTY, () => 0);
|
||||
|
||||
// Recognize token
|
||||
var recognized = await RecognizeTokenAsync(dc.Context, cancellationToken).ConfigureAwait(false);
|
||||
var recognized = await RecognizeTokenAsync(dc, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
// Check for timeout
|
||||
var state = dc.ActiveDialog.State;
|
||||
|
@ -185,7 +190,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Input
|
|||
{
|
||||
if (this.Property != null)
|
||||
{
|
||||
dc.GetState().SetValue(this.Property, null);
|
||||
dcState.SetValue(this.Property.GetValue(dcState), null);
|
||||
}
|
||||
|
||||
// if the token fetch request times out, complete the prompt with no result.
|
||||
|
@ -212,33 +217,33 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Input
|
|||
{
|
||||
if (this.Property != null)
|
||||
{
|
||||
dc.GetState().SetValue(this.Property, recognized.Value);
|
||||
dcState.SetValue(this.Property.GetValue(dcState), recognized.Value);
|
||||
}
|
||||
|
||||
return await dc.EndDialogAsync(recognized.Value, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
else if (this.MaxTurnCount == null || turnCount < this.MaxTurnCount)
|
||||
else if (this.MaxTurnCount == null || turnCount < this.MaxTurnCount.GetValue(dcState))
|
||||
{
|
||||
// increase the turnCount as last step
|
||||
dc.GetState().SetValue(TURN_COUNT_PROPERTY, turnCount + 1);
|
||||
dcState.SetValue(TURN_COUNT_PROPERTY, turnCount + 1);
|
||||
var prompt = await this.OnRenderPrompt(dc, inputState).ConfigureAwait(false);
|
||||
await dc.Context.SendActivityAsync(prompt).ConfigureAwait(false);
|
||||
await SendOAuthCardAsync(dc.Context, promptOptions?.Prompt, cancellationToken).ConfigureAwait(false);
|
||||
await SendOAuthCardAsync(dc, promptOptions?.Prompt, cancellationToken).ConfigureAwait(false);
|
||||
return Dialog.EndOfTurn;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (this.DefaultValue != null)
|
||||
{
|
||||
var (value, error) = new ExpressionEngine().Parse(this.DefaultValue).TryEvaluate(dc.GetState());
|
||||
var (value, _) = this.DefaultValue.TryGetValue(dcState);
|
||||
if (this.DefaultValueResponse != null)
|
||||
{
|
||||
var response = await this.DefaultValueResponse.BindToData(dc.Context, dc.GetState()).ConfigureAwait(false);
|
||||
var response = await this.DefaultValueResponse.BindToData(dc.Context, dcState).ConfigureAwait(false);
|
||||
await dc.Context.SendActivityAsync(response).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
// set output property
|
||||
dc.GetState().SetValue(this.Property, value);
|
||||
dcState.SetValue(this.Property.GetValue(dcState), value);
|
||||
return await dc.EndDialogAsync(value).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
@ -250,38 +255,41 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Input
|
|||
/// <summary>
|
||||
/// Attempts to get the user's token.
|
||||
/// </summary>
|
||||
/// <param name="turnContext">Context for the current turn of conversation with the user.</param>
|
||||
/// <param name="dc">DialogContext for the current turn of conversation with the user.</param>
|
||||
/// <param name="cancellationToken">A cancellation token that can be used by other objects
|
||||
/// or threads to receive notice of cancellation.</param>
|
||||
/// <returns>A task that represents the work queued to execute.</returns>
|
||||
/// <remarks>If the task is successful and user already has a token or the user successfully signs in,
|
||||
/// the result contains the user's token.</remarks>
|
||||
public async Task<TokenResponse> GetUserTokenAsync(ITurnContext turnContext, CancellationToken cancellationToken = default(CancellationToken))
|
||||
public async Task<TokenResponse> GetUserTokenAsync(DialogContext dc, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
if (!(turnContext.Adapter is IUserTokenProvider adapter))
|
||||
if (!(dc.Context.Adapter is IUserTokenProvider adapter))
|
||||
{
|
||||
throw new InvalidOperationException("OAuthPrompt.GetUserToken(): not supported by the current adapter");
|
||||
}
|
||||
|
||||
return await adapter.GetUserTokenAsync(turnContext, ConnectionName, null, cancellationToken).ConfigureAwait(false);
|
||||
var dcState = dc.GetState();
|
||||
return await adapter.GetUserTokenAsync(dc.Context, ConnectionName.GetValue(dcState), null, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Signs out the user.
|
||||
/// </summary>
|
||||
/// <param name="turnContext">Context for the current turn of conversation with the user.</param>
|
||||
/// <param name="dc">DialogContext for the current turn of conversation with the user.</param>
|
||||
/// <param name="cancellationToken">A cancellation token that can be used by other objects
|
||||
/// or threads to receive notice of cancellation.</param>
|
||||
/// <returns>A task that represents the work queued to execute.</returns>
|
||||
public async Task SignOutUserAsync(ITurnContext turnContext, CancellationToken cancellationToken = default(CancellationToken))
|
||||
public async Task SignOutUserAsync(DialogContext dc, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
if (!(turnContext.Adapter is IUserTokenProvider adapter))
|
||||
if (!(dc.Context.Adapter is IUserTokenProvider adapter))
|
||||
{
|
||||
throw new InvalidOperationException("OAuthPrompt.SignOutUser(): not supported by the current adapter");
|
||||
}
|
||||
|
||||
var dcState = dc.GetState();
|
||||
|
||||
// Sign out user
|
||||
await adapter.SignOutUserAsync(turnContext, ConnectionName, turnContext.Activity?.From?.Id, cancellationToken).ConfigureAwait(false);
|
||||
await adapter.SignOutUserAsync(dc.Context, ConnectionName.GetValue(dcState), dc.Context.Activity?.From?.Id, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
protected override Task<InputState> OnRecognizeInput(DialogContext dc)
|
||||
|
@ -289,15 +297,17 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Input
|
|||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private async Task SendOAuthCardAsync(ITurnContext turnContext, IMessageActivity prompt, CancellationToken cancellationToken = default(CancellationToken))
|
||||
private async Task SendOAuthCardAsync(DialogContext dc, IMessageActivity prompt, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
BotAssert.ContextNotNull(turnContext);
|
||||
var turnContext = dc.Context;
|
||||
|
||||
if (!(turnContext.Adapter is IUserTokenProvider adapter))
|
||||
{
|
||||
throw new InvalidOperationException("OAuthPrompt.Prompt(): not supported by the current adapter");
|
||||
}
|
||||
|
||||
var dcState = dc.GetState();
|
||||
|
||||
// Ensure prompt initialized
|
||||
if (prompt == null)
|
||||
{
|
||||
|
@ -314,18 +324,18 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Input
|
|||
{
|
||||
if (!prompt.Attachments.Any(a => a.Content is SigninCard))
|
||||
{
|
||||
var link = await adapter.GetOauthSignInLinkAsync(turnContext, ConnectionName, cancellationToken).ConfigureAwait(false);
|
||||
var link = await adapter.GetOauthSignInLinkAsync(turnContext, ConnectionName?.GetValue(dcState), cancellationToken).ConfigureAwait(false);
|
||||
prompt.Attachments.Add(new Attachment
|
||||
{
|
||||
ContentType = SigninCard.ContentType,
|
||||
Content = new SigninCard
|
||||
{
|
||||
Text = Text,
|
||||
Text = Text?.GetValue(dcState),
|
||||
Buttons = new[]
|
||||
{
|
||||
new CardAction
|
||||
{
|
||||
Title = Title,
|
||||
Title = Title?.GetValue(dcState),
|
||||
Value = link,
|
||||
Type = ActionTypes.Signin,
|
||||
},
|
||||
|
@ -341,14 +351,14 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Input
|
|||
ContentType = OAuthCard.ContentType,
|
||||
Content = new OAuthCard
|
||||
{
|
||||
Text = Text,
|
||||
ConnectionName = ConnectionName,
|
||||
Text = Text?.GetValue(dcState),
|
||||
ConnectionName = ConnectionName?.GetValue(dcState),
|
||||
Buttons = new[]
|
||||
{
|
||||
new CardAction
|
||||
{
|
||||
Title = Title,
|
||||
Text = Text,
|
||||
Title = Title?.GetValue(dcState),
|
||||
Text = Text?.GetValue(dcState),
|
||||
Type = ActionTypes.Signin,
|
||||
},
|
||||
},
|
||||
|
@ -365,22 +375,24 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Input
|
|||
await turnContext.SendActivityAsync(prompt, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private async Task<PromptRecognizerResult<TokenResponse>> RecognizeTokenAsync(ITurnContext turnContext, CancellationToken cancellationToken = default(CancellationToken))
|
||||
private async Task<PromptRecognizerResult<TokenResponse>> RecognizeTokenAsync(DialogContext dc, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
var dcState = dc.GetState();
|
||||
|
||||
var result = new PromptRecognizerResult<TokenResponse>();
|
||||
if (IsTokenResponseEvent(turnContext))
|
||||
if (IsTokenResponseEvent(dc.Context))
|
||||
{
|
||||
var tokenResponseObject = turnContext.Activity.Value as JObject;
|
||||
var tokenResponseObject = dc.Context.Activity.Value as JObject;
|
||||
var token = tokenResponseObject?.ToObject<TokenResponse>();
|
||||
result.Succeeded = true;
|
||||
result.Value = token;
|
||||
}
|
||||
else if (IsTeamsVerificationInvoke(turnContext))
|
||||
else if (IsTeamsVerificationInvoke(dc.Context))
|
||||
{
|
||||
var magicCodeObject = turnContext.Activity.Value as JObject;
|
||||
var magicCodeObject = dc.Context.Activity.Value as JObject;
|
||||
var magicCode = magicCodeObject.GetValue("state")?.ToString();
|
||||
|
||||
if (!(turnContext.Adapter is IUserTokenProvider adapter))
|
||||
if (!(dc.Context.Adapter is IUserTokenProvider adapter))
|
||||
{
|
||||
throw new InvalidOperationException("OAuthPrompt.Recognize(): not supported by the current adapter");
|
||||
}
|
||||
|
@ -394,36 +406,36 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Input
|
|||
// progress) retry in that case.
|
||||
try
|
||||
{
|
||||
var token = await adapter.GetUserTokenAsync(turnContext, ConnectionName, magicCode, cancellationToken).ConfigureAwait(false);
|
||||
var token = await adapter.GetUserTokenAsync(dc.Context, ConnectionName.GetValue(dcState), magicCode, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
if (token != null)
|
||||
{
|
||||
result.Succeeded = true;
|
||||
result.Value = token;
|
||||
|
||||
await turnContext.SendActivityAsync(new Activity { Type = ActivityTypesEx.InvokeResponse }, cancellationToken).ConfigureAwait(false);
|
||||
await dc.Context.SendActivityAsync(new Activity { Type = ActivityTypesEx.InvokeResponse }, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
await turnContext.SendActivityAsync(new Activity { Type = ActivityTypesEx.InvokeResponse, Value = new InvokeResponse { Status = 404 } }, cancellationToken).ConfigureAwait(false);
|
||||
await dc.Context.SendActivityAsync(new Activity { Type = ActivityTypesEx.InvokeResponse, Value = new InvokeResponse { Status = 404 } }, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
await turnContext.SendActivityAsync(new Activity { Type = ActivityTypesEx.InvokeResponse, Value = new InvokeResponse { Status = 500 } }, cancellationToken).ConfigureAwait(false);
|
||||
await dc.Context.SendActivityAsync(new Activity { Type = ActivityTypesEx.InvokeResponse, Value = new InvokeResponse { Status = 500 } }, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
else if (turnContext.Activity.Type == ActivityTypes.Message)
|
||||
else if (dc.Context.Activity.Type == ActivityTypes.Message)
|
||||
{
|
||||
var matched = _magicCodeRegex.Match(turnContext.Activity.Text);
|
||||
var matched = _magicCodeRegex.Match(dc.Context.Activity.Text);
|
||||
if (matched.Success)
|
||||
{
|
||||
if (!(turnContext.Adapter is IUserTokenProvider adapter))
|
||||
if (!(dc.Context.Adapter is IUserTokenProvider adapter))
|
||||
{
|
||||
throw new InvalidOperationException("OAuthPrompt.Recognize(): not supported by the current adapter");
|
||||
}
|
||||
|
||||
var token = await adapter.GetUserTokenAsync(turnContext, ConnectionName, matched.Value, cancellationToken).ConfigureAwait(false);
|
||||
var token = await adapter.GetUserTokenAsync(dc.Context, ConnectionName.GetValue(dcState), matched.Value, cancellationToken).ConfigureAwait(false);
|
||||
if (token != null)
|
||||
{
|
||||
result.Succeeded = true;
|
||||
|
|
|
@ -23,27 +23,28 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Input
|
|||
}
|
||||
|
||||
[JsonProperty("outputFormat")]
|
||||
public string OutputFormat { get; set; }
|
||||
public StringExpression OutputFormat { get; set; }
|
||||
|
||||
protected override Task<InputState> OnRecognizeInput(DialogContext dc)
|
||||
{
|
||||
var input = dc.GetState().GetValue<string>(VALUE_PROPERTY);
|
||||
var dcState = dc.GetState();
|
||||
|
||||
if (!string.IsNullOrEmpty(OutputFormat))
|
||||
var input = dcState.GetValue<string>(VALUE_PROPERTY);
|
||||
|
||||
if (this.OutputFormat != null)
|
||||
{
|
||||
var outputExpression = new ExpressionEngine().Parse(OutputFormat);
|
||||
var (outputValue, error) = outputExpression.TryEvaluate(dc.GetState());
|
||||
var (outputValue, error) = this.OutputFormat.TryGetValue(dcState);
|
||||
if (error == null)
|
||||
{
|
||||
input = outputValue.ToString();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception($"In TextInput, OutputFormat Expression evaluation resulted in an error. Expression: {outputExpression.ToString()}. Error: {error}");
|
||||
throw new Exception($"In TextInput, OutputFormat Expression evaluation resulted in an error. Expression: {OutputFormat.ToString()}. Error: {error}");
|
||||
}
|
||||
}
|
||||
|
||||
dc.GetState().SetValue(VALUE_PROPERTY, input);
|
||||
dcState.SetValue(VALUE_PROPERTY, input);
|
||||
return input.Length > 0 ? Task.FromResult(InputState.Valid) : Task.FromResult(InputState.Unrecognized);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// Licensed under the MIT License.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Bot.Builder.Dialogs.Adaptive.Generators;
|
||||
using Microsoft.Bot.Builder.Dialogs.Declarative;
|
||||
using Microsoft.Bot.Builder.Dialogs.Declarative.Resources;
|
||||
|
@ -10,6 +11,8 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive
|
|||
{
|
||||
public static class LGAdapterExtensions
|
||||
{
|
||||
private static Dictionary<ResourceExplorer, LanguageGeneratorManager> languageGeneratorManagers = new Dictionary<ResourceExplorer, LanguageGeneratorManager>();
|
||||
|
||||
/// <summary>
|
||||
/// Register default LG file as language generation.
|
||||
/// </summary>
|
||||
|
@ -54,9 +57,19 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive
|
|||
public static BotAdapter UseLanguageGeneration(this BotAdapter botAdapter, ResourceExplorer resourceExplorer, ILanguageGenerator languageGenerator)
|
||||
{
|
||||
DeclarativeTypeLoader.AddComponent(new LanguageGenerationComponentRegistration());
|
||||
botAdapter.Use(new RegisterClassMiddleware<LanguageGeneratorManager>(new LanguageGeneratorManager(resourceExplorer ?? throw new ArgumentNullException(nameof(resourceExplorer)))));
|
||||
|
||||
lock (languageGeneratorManagers)
|
||||
{
|
||||
if (!languageGeneratorManagers.TryGetValue(resourceExplorer ?? throw new ArgumentNullException(nameof(resourceExplorer)), out var lgm))
|
||||
{
|
||||
lgm = new LanguageGeneratorManager(resourceExplorer);
|
||||
languageGeneratorManagers[resourceExplorer] = lgm;
|
||||
}
|
||||
|
||||
botAdapter.Use(new RegisterClassMiddleware<LanguageGeneratorManager>(lgm));
|
||||
botAdapter.Use(new RegisterClassMiddleware<ILanguageGenerator>(languageGenerator ?? throw new ArgumentNullException(nameof(languageGenerator))));
|
||||
return botAdapter;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -383,13 +383,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Memory
|
|||
|
||||
public bool TryGetValue(string key, out object value)
|
||||
{
|
||||
value = default;
|
||||
if (this.TryGetValue<object>(key, out var result))
|
||||
{
|
||||
value = result;
|
||||
}
|
||||
|
||||
return true;
|
||||
return this.TryGetValue<object>(key, out value);
|
||||
}
|
||||
|
||||
public void Add(KeyValuePair<string, object> item)
|
||||
|
@ -461,6 +455,8 @@ namespace Microsoft.Bot.Builder.Dialogs.Memory
|
|||
public bool AnyPathChanged(uint counter, IEnumerable<string> paths)
|
||||
{
|
||||
var found = false;
|
||||
if (paths != null)
|
||||
{
|
||||
foreach (var path in paths)
|
||||
{
|
||||
if (GetValue<uint>(PathTracker + "." + path) > counter)
|
||||
|
@ -469,6 +465,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Memory
|
|||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Bot.Builder.Dialogs.Adaptive.Converters;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Microsoft.Bot.Builder.Dialogs.Adaptive
|
||||
{
|
||||
/// <summary>
|
||||
/// ArrayExpression - represents a property which is either a value of array of T or a string expression to bind to a array of T.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">type of object in the array.</typeparam>
|
||||
/// <remarks>String values are always interpreted as an expression, whether it has '=' prefix or not.</remarks>
|
||||
public class ArrayExpression<T> : ExpressionProperty<List<T>>
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ArrayExpression{T}"/> class.
|
||||
/// </summary>
|
||||
public ArrayExpression()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ArrayExpression{T}"/> class.
|
||||
/// </summary>
|
||||
/// <param name="value">collection of (T).</param>
|
||||
public ArrayExpression(List<T> value)
|
||||
: base(value)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ArrayExpression{T}"/> class.
|
||||
/// </summary>
|
||||
/// <param name="expression">expression which evaluates to array.</param>
|
||||
public ArrayExpression(string expression)
|
||||
: base(expression)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ArrayExpression{T}"/> class.
|
||||
/// </summary>
|
||||
/// <param name="value">JToken which is either a collection of (T) or expression which evalutes to array.</param>
|
||||
public ArrayExpression(JToken value)
|
||||
: base(value)
|
||||
{
|
||||
}
|
||||
|
||||
public static implicit operator ArrayExpression<T>(List<T> value) => new ArrayExpression<T>(value);
|
||||
|
||||
public static implicit operator ArrayExpression<T>(string value) => new ArrayExpression<T>(value);
|
||||
|
||||
public static implicit operator ArrayExpression<T>(JToken value) => new ArrayExpression<T>(value);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
using Microsoft.Bot.Builder.Dialogs.Adaptive.Converters;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Microsoft.Bot.Builder.Dialogs.Adaptive
|
||||
{
|
||||
/// <summary>
|
||||
/// BoolExpression - represents a property which is either a boolean or a string expression which resolves to a boolean.
|
||||
/// </summary>
|
||||
/// <remarks>String values are always interpreted as an expression, whether it has '=' prefix or not.</remarks>
|
||||
[JsonConverter(typeof(BoolExpressionConverter))]
|
||||
public class BoolExpression : ExpressionProperty<bool>
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="BoolExpression"/> class.
|
||||
/// </summary>
|
||||
public BoolExpression()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="BoolExpression"/> class.
|
||||
/// </summary>
|
||||
/// <param name="value">bool value.</param>
|
||||
public BoolExpression(bool value)
|
||||
: base(value)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="BoolExpression"/> class.
|
||||
/// </summary>
|
||||
/// <param name="expression">expression to resolve to bool.</param>
|
||||
public BoolExpression(string expression)
|
||||
: base(expression)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="BoolExpression"/> class.
|
||||
/// </summary>
|
||||
/// <param name="value">expression or value to resolve to bool.</param>
|
||||
public BoolExpression(JToken value)
|
||||
: base(value)
|
||||
{
|
||||
}
|
||||
|
||||
public static implicit operator BoolExpression(bool value) => new BoolExpression(value);
|
||||
|
||||
public static implicit operator BoolExpression(string value) => new BoolExpression(value);
|
||||
|
||||
public static implicit operator BoolExpression(JToken value) => new BoolExpression(value);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Data.SqlTypes;
|
||||
using Microsoft.Bot.Expressions;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Converters
|
||||
{
|
||||
/// <summary>
|
||||
/// Converter which allows json to be expression to object or static object.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the items of the array.</typeparam>
|
||||
public class ArrayExpressionConverter<T> : JsonConverter<ArrayExpression<T>>
|
||||
{
|
||||
public override bool CanRead => true;
|
||||
|
||||
public override ArrayExpression<T> ReadJson(JsonReader reader, Type objectType, ArrayExpression<T> existingValue, bool hasExistingValue, JsonSerializer serializer)
|
||||
{
|
||||
if (reader.ValueType == typeof(string))
|
||||
{
|
||||
return new ArrayExpression<T>((string)reader.Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
return new ArrayExpression<T>(JToken.Load(reader));
|
||||
}
|
||||
}
|
||||
|
||||
public override void WriteJson(JsonWriter writer, ArrayExpression<T> value, JsonSerializer serializer)
|
||||
{
|
||||
if (value.Expression != null)
|
||||
{
|
||||
serializer.Serialize(writer, value.ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
serializer.Serialize(writer, value.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
using System;
|
||||
using System.Data.SqlTypes;
|
||||
using Microsoft.Bot.Expressions;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Converters
|
||||
{
|
||||
/// <summary>
|
||||
/// Converter which allows json to be expression to object or static object.
|
||||
/// </summary>
|
||||
public class BoolExpressionConverter : JsonConverter<BoolExpression>
|
||||
{
|
||||
public BoolExpressionConverter()
|
||||
{
|
||||
}
|
||||
|
||||
public override bool CanRead => true;
|
||||
|
||||
public override BoolExpression ReadJson(JsonReader reader, Type objectType, BoolExpression existingValue, bool hasExistingValue, JsonSerializer serializer)
|
||||
{
|
||||
if (reader.ValueType == typeof(string))
|
||||
{
|
||||
return new BoolExpression((string)reader.Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
return new BoolExpression(JToken.Load(reader));
|
||||
}
|
||||
}
|
||||
|
||||
public override void WriteJson(JsonWriter writer, BoolExpression value, JsonSerializer serializer)
|
||||
{
|
||||
if (value.Expression != null)
|
||||
{
|
||||
serializer.Serialize(writer, value.ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
serializer.Serialize(writer, value.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
using System;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Input
|
||||
{
|
||||
/// <summary>
|
||||
/// Converter for ChoiceSet - allows string or array initializers.
|
||||
/// </summary>
|
||||
public class ChoiceSetConverter : JsonConverter<ChoiceSet>
|
||||
{
|
||||
public override ChoiceSet ReadJson(JsonReader reader, Type objectType, ChoiceSet existingValue, bool hasExistingValue, JsonSerializer serializer)
|
||||
{
|
||||
if (reader.ValueType == typeof(string))
|
||||
{
|
||||
return new ChoiceSet((string)reader.Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
return new ChoiceSet(JArray.Load(reader));
|
||||
}
|
||||
}
|
||||
|
||||
public override void WriteJson(JsonWriter writer, ChoiceSet choiceSet, JsonSerializer serializer)
|
||||
{
|
||||
writer.WriteStartArray();
|
||||
foreach (var choice in choiceSet)
|
||||
{
|
||||
JObject.FromObject(choice).WriteTo(writer);
|
||||
}
|
||||
|
||||
writer.WriteEndArray();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.SqlTypes;
|
||||
using System.IO;
|
||||
using Microsoft.Bot.Builder.Dialogs.Debugging;
|
||||
using Microsoft.Bot.Builder.Dialogs.Declarative.Converters;
|
||||
using Microsoft.Bot.Builder.Dialogs.Declarative.Resolvers;
|
||||
using Microsoft.Bot.Expressions;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Converters
|
||||
{
|
||||
/// <summary>
|
||||
/// Converter which allows json to be expression to object or static object.
|
||||
/// </summary>
|
||||
public class DialogExpressionConverter : JsonConverter<DialogExpression>
|
||||
{
|
||||
private readonly InterfaceConverter<Dialog> converter;
|
||||
|
||||
public DialogExpressionConverter(IRefResolver refResolver, ISourceMap sourceMap, Stack<string> paths)
|
||||
{
|
||||
this.converter = new InterfaceConverter<Dialog>(refResolver, sourceMap, paths);
|
||||
}
|
||||
|
||||
public override bool CanRead => true;
|
||||
|
||||
public override DialogExpression ReadJson(JsonReader reader, Type objectType, DialogExpression existingValue, bool hasExistingValue, JsonSerializer serializer)
|
||||
{
|
||||
if (reader.ValueType == typeof(string))
|
||||
{
|
||||
var id = (string)reader.Value;
|
||||
if (id.StartsWith("="))
|
||||
{
|
||||
return new DialogExpression(id);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
return new DialogExpression((Dialog)this.converter.ReadJson(new JsonTextReader(new StringReader($"\"{id}\"")), objectType, existingValue, serializer));
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return new DialogExpression($"='{id}'");
|
||||
}
|
||||
}
|
||||
|
||||
return new DialogExpression((Dialog)this.converter.ReadJson(reader, objectType, existingValue, serializer));
|
||||
}
|
||||
|
||||
public override void WriteJson(JsonWriter writer, DialogExpression value, JsonSerializer serializer)
|
||||
{
|
||||
if (value.Expression != null)
|
||||
{
|
||||
serializer.Serialize(writer, value.ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
serializer.Serialize(writer, value.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
using System;
|
||||
using System.Data.SqlTypes;
|
||||
using Microsoft.Bot.Expressions;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Converters
|
||||
{
|
||||
/// <summary>
|
||||
/// Converter which allows json to be expression to object or static object.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The enum type to construct.</typeparam>
|
||||
public class EnumExpressionConverter<T> : JsonConverter<EnumExpression<T>>
|
||||
where T : struct
|
||||
{
|
||||
public EnumExpressionConverter()
|
||||
{
|
||||
}
|
||||
|
||||
public override bool CanRead => true;
|
||||
|
||||
public override EnumExpression<T> ReadJson(JsonReader reader, Type objectType, EnumExpression<T> existingValue, bool hasExistingValue, JsonSerializer serializer)
|
||||
{
|
||||
if (reader.ValueType == typeof(string))
|
||||
{
|
||||
return new EnumExpression<T>((string)reader.Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
return new EnumExpression<T>(JToken.Load(reader));
|
||||
}
|
||||
}
|
||||
|
||||
public override void WriteJson(JsonWriter writer, EnumExpression<T> value, JsonSerializer serializer)
|
||||
{
|
||||
if (value.Expression != null)
|
||||
{
|
||||
serializer.Serialize(writer, value.ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
serializer.Serialize(writer, value.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
using System;
|
||||
using System.Data.SqlTypes;
|
||||
using Microsoft.Bot.Expressions;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Converters
|
||||
{
|
||||
/// <summary>
|
||||
/// Converter which allows json to be expression to object or static object.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The property type to construct.</typeparam>
|
||||
public class ExpressionPropertyConverter<T> : JsonConverter<ExpressionProperty<T>>
|
||||
{
|
||||
public override bool CanRead => true;
|
||||
|
||||
public override ExpressionProperty<T> ReadJson(JsonReader reader, Type objectType, ExpressionProperty<T> existingValue, bool hasExistingValue, JsonSerializer serializer)
|
||||
{
|
||||
if (reader.ValueType == typeof(string))
|
||||
{
|
||||
return new ExpressionProperty<T>((string)reader.Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
return new ExpressionProperty<T>(JToken.Load(reader));
|
||||
}
|
||||
}
|
||||
|
||||
public override void WriteJson(JsonWriter writer, ExpressionProperty<T> value, JsonSerializer serializer)
|
||||
{
|
||||
if (value.Expression != null)
|
||||
{
|
||||
serializer.Serialize(writer, value.ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
serializer.Serialize(writer, value.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
using System;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Converters
|
||||
{
|
||||
/// <summary>
|
||||
/// Converter which allows json to be expression to object or static object.
|
||||
/// </summary>
|
||||
public class IntExpressionConverter : JsonConverter<IntExpression>
|
||||
{
|
||||
public IntExpressionConverter()
|
||||
{
|
||||
}
|
||||
|
||||
public override bool CanRead => true;
|
||||
|
||||
public override IntExpression ReadJson(JsonReader reader, Type objectType, IntExpression existingValue, bool hasExistingValue, JsonSerializer serializer)
|
||||
{
|
||||
if (reader.ValueType == typeof(string))
|
||||
{
|
||||
return new IntExpression((string)reader.Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
return new IntExpression(JToken.Load(reader));
|
||||
}
|
||||
}
|
||||
|
||||
public override void WriteJson(JsonWriter writer, IntExpression value, JsonSerializer serializer)
|
||||
{
|
||||
if (value.Expression != null)
|
||||
{
|
||||
serializer.Serialize(writer, value.ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
serializer.Serialize(writer, value.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
using System;
|
||||
using System.Data.SqlTypes;
|
||||
using Microsoft.Bot.Expressions;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Converters
|
||||
{
|
||||
/// <summary>
|
||||
/// Converter which allows json to be expression to object or static object.
|
||||
/// </summary>
|
||||
public class NumberExpressionConverter : JsonConverter<NumberExpression>
|
||||
{
|
||||
public NumberExpressionConverter()
|
||||
{
|
||||
}
|
||||
|
||||
public override bool CanRead => true;
|
||||
|
||||
public override NumberExpression ReadJson(JsonReader reader, Type objectType, NumberExpression existingValue, bool hasExistingValue, JsonSerializer serializer)
|
||||
{
|
||||
if (reader.ValueType == typeof(string))
|
||||
{
|
||||
return new NumberExpression((string)reader.Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
return new NumberExpression(JToken.Load(reader));
|
||||
}
|
||||
}
|
||||
|
||||
public override void WriteJson(JsonWriter writer, NumberExpression value, JsonSerializer serializer)
|
||||
{
|
||||
if (value.Expression != null)
|
||||
{
|
||||
serializer.Serialize(writer, value.ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
serializer.Serialize(writer, value.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
using System;
|
||||
using System.Data.SqlTypes;
|
||||
using Microsoft.Bot.Expressions;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Converters
|
||||
{
|
||||
/// <summary>
|
||||
/// Converter which allows json to be expression to object or static object.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The property type to construct.</typeparam>
|
||||
public class ObjectExpressionConverter<T> : JsonConverter<ObjectExpression<T>>
|
||||
{
|
||||
public override bool CanRead => true;
|
||||
|
||||
public override ObjectExpression<T> ReadJson(JsonReader reader, Type objectType, ObjectExpression<T> existingValue, bool hasExistingValue, JsonSerializer serializer)
|
||||
{
|
||||
if (reader.ValueType == typeof(string))
|
||||
{
|
||||
return new ObjectExpression<T>((string)reader.Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
return new ObjectExpression<T>(JToken.Load(reader));
|
||||
}
|
||||
}
|
||||
|
||||
public override void WriteJson(JsonWriter writer, ObjectExpression<T> value, JsonSerializer serializer)
|
||||
{
|
||||
if (value.Expression != null)
|
||||
{
|
||||
serializer.Serialize(writer, value.ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
serializer.Serialize(writer, value.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
using System;
|
||||
using System.Data.SqlTypes;
|
||||
using Microsoft.Bot.Expressions;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Converters
|
||||
{
|
||||
/// <summary>
|
||||
/// Converter which allows json to be expression to object or static object.
|
||||
/// </summary>
|
||||
public class StringExpressionConverter : JsonConverter<StringExpression>
|
||||
{
|
||||
public StringExpressionConverter()
|
||||
{
|
||||
}
|
||||
|
||||
public override StringExpression ReadJson(JsonReader reader, Type objectType, StringExpression existingValue, bool hasExistingValue, JsonSerializer serializer)
|
||||
{
|
||||
if (reader.ValueType == typeof(string))
|
||||
{
|
||||
return new StringExpression((string)reader.Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
return new StringExpression(JToken.Load(reader));
|
||||
}
|
||||
}
|
||||
|
||||
public override void WriteJson(JsonWriter writer, StringExpression value, JsonSerializer serializer)
|
||||
{
|
||||
if (value.Expression != null)
|
||||
{
|
||||
serializer.Serialize(writer, value.ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
serializer.Serialize(writer, value.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
using System;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Converters
|
||||
{
|
||||
/// <summary>
|
||||
/// Converter which allows json to be expression to object or static object.
|
||||
/// </summary>
|
||||
public class ValueExpressionConverter : JsonConverter<ValueExpression>
|
||||
{
|
||||
public ValueExpressionConverter()
|
||||
{
|
||||
}
|
||||
|
||||
public override bool CanRead => true;
|
||||
|
||||
public override ValueExpression ReadJson(JsonReader reader, Type objectType, ValueExpression existingValue, bool hasExistingValue, JsonSerializer serializer)
|
||||
{
|
||||
if (reader.ValueType == typeof(string))
|
||||
{
|
||||
return new ValueExpression((string)reader.Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
return new ValueExpression(JToken.Load(reader));
|
||||
}
|
||||
}
|
||||
|
||||
public override void WriteJson(JsonWriter writer, ValueExpression value, JsonSerializer serializer)
|
||||
{
|
||||
if (value.Expression != null)
|
||||
{
|
||||
serializer.Serialize(writer, value.ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
serializer.Serialize(writer, value.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
using Microsoft.Bot.Builder.Dialogs.Adaptive.Converters;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Microsoft.Bot.Builder.Dialogs.Adaptive
|
||||
{
|
||||
/// <summary>
|
||||
/// DialogExpression - represents a property which is either a Dialog or a string expression for a dialogId.
|
||||
/// </summary>
|
||||
/// <remarks>String values are always interpreted as a string with interpolation, unless it has '=' prefix or not. The result is interpreted as a resource Id or dialogId.</remarks>
|
||||
public class DialogExpression : ObjectExpression<Dialog>
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="DialogExpression"/> class.
|
||||
/// </summary>
|
||||
public DialogExpression()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="DialogExpression"/> class.
|
||||
/// </summary>
|
||||
/// <param name="value">dialog value.</param>
|
||||
public DialogExpression(Dialog value)
|
||||
: base(value)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="DialogExpression"/> class.
|
||||
/// </summary>
|
||||
/// <param name="dialogIdOrExpression">dialogId or expression to dialogId.</param>
|
||||
public DialogExpression(string dialogIdOrExpression)
|
||||
: base(dialogIdOrExpression)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="DialogExpression"/> class.
|
||||
/// </summary>
|
||||
/// <param name="value">JToken which is either dialog or dialogId.</param>
|
||||
public DialogExpression(JToken value)
|
||||
: base(value)
|
||||
{
|
||||
}
|
||||
|
||||
public static implicit operator DialogExpression(Dialog value) => new DialogExpression(value);
|
||||
|
||||
public static implicit operator DialogExpression(string dialogIdOrExpression) => new DialogExpression(dialogIdOrExpression);
|
||||
|
||||
public static implicit operator DialogExpression(JToken value) => new DialogExpression(value);
|
||||
|
||||
public override void SetValue(object value)
|
||||
{
|
||||
if (value is string str)
|
||||
{
|
||||
if (!str.StartsWith("="))
|
||||
{
|
||||
// Resource Id's will be resolved to actual dialog value
|
||||
// if it's not a = then we want to convert to a constant string expressions to represent a
|
||||
// external dialog id resolved by dc.FindDialog()
|
||||
value = $"='{str}'";
|
||||
}
|
||||
}
|
||||
|
||||
base.SetValue(value);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
using System;
|
||||
using Microsoft.Bot.Builder.Dialogs.Adaptive.Converters;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Microsoft.Bot.Builder.Dialogs.Adaptive
|
||||
{
|
||||
/// <summary>
|
||||
/// EnumExpression - represents a property which is either a enum(T) or a string expression which resolves to a enum(T).
|
||||
/// </summary>
|
||||
/// <typeparam name="T">type of enum.</typeparam>
|
||||
/// <remarks>String values are always interpreted as an enum, unless it has '=' prefix in which case it is evaluated as a expression.</remarks>
|
||||
public class EnumExpression<T> : ExpressionProperty<T>
|
||||
where T : struct
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="EnumExpression{T}"/> class.
|
||||
/// </summary>
|
||||
public EnumExpression()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="EnumExpression{T}"/> class.
|
||||
/// </summary>
|
||||
/// <param name="value">value of T.</param>
|
||||
public EnumExpression(T value)
|
||||
: base(value)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="EnumExpression{T}"/> class.
|
||||
/// </summary>
|
||||
/// <param name="expression">expression to resolve to an enum.</param>
|
||||
public EnumExpression(string expression)
|
||||
: base(expression)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="EnumExpression{T}"/> class.
|
||||
/// </summary>
|
||||
/// <param name="value">jtoken value to resolve to an enum.</param>
|
||||
public EnumExpression(JToken value)
|
||||
: base(value)
|
||||
{
|
||||
}
|
||||
|
||||
public static implicit operator EnumExpression<T>(T value) => new EnumExpression<T>(value);
|
||||
|
||||
public static implicit operator EnumExpression<T>(string enumOrExpression) => new EnumExpression<T>(enumOrExpression);
|
||||
|
||||
public static implicit operator EnumExpression<T>(JToken value) => new EnumExpression<T>(value);
|
||||
|
||||
public override void SetValue(object value)
|
||||
{
|
||||
if (value is string stringOrExpression)
|
||||
{
|
||||
// if the expression is the enum value, then use that as the value, else it is an expression.
|
||||
if (Enum.TryParse<T>(stringOrExpression.TrimStart('='), ignoreCase: true, out T val))
|
||||
{
|
||||
this.Value = val;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
base.SetValue(value);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,136 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Text;
|
||||
using Microsoft.Bot.Builder.LanguageGeneration;
|
||||
using Microsoft.Bot.Expressions;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Microsoft.Bot.Builder.Dialogs.Adaptive
|
||||
{
|
||||
/// <summary>
|
||||
/// Base class which defines a Expression or value for a property.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">type of object the expression should evaluate to.</typeparam>
|
||||
public class ExpressionProperty<T>
|
||||
{
|
||||
public ExpressionProperty()
|
||||
{
|
||||
}
|
||||
|
||||
public ExpressionProperty(object value)
|
||||
{
|
||||
SetValue(value);
|
||||
}
|
||||
|
||||
public T Value { get; set; } = default(T);
|
||||
|
||||
public Expression Expression { get; set; }
|
||||
|
||||
public new string ToString()
|
||||
{
|
||||
if (this.Expression != null)
|
||||
{
|
||||
return $"={this.Expression}";
|
||||
}
|
||||
|
||||
return this.Value?.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This will return the existing expression or ConstantExpression(Value) if the value is non-complex type.
|
||||
/// </summary>
|
||||
/// <returns>expression.</returns>
|
||||
public Expression ToExpression()
|
||||
{
|
||||
if (this.Expression != null)
|
||||
{
|
||||
return this.Expression;
|
||||
}
|
||||
|
||||
if (this.Value is string || this.Value.IsNumber() || this.Value.IsInteger() || this.Value is bool || this.Value.GetType().IsEnum)
|
||||
{
|
||||
return new ExpressionEngine().Parse(this.Value.ToString());
|
||||
}
|
||||
|
||||
// return expression for json object
|
||||
return new ExpressionEngine().Parse($"json({JsonConvert.SerializeObject(this.Value)})");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the value.
|
||||
/// </summary>
|
||||
/// <param name="data">data to use for expression binding.</param>
|
||||
/// <returns>value or default(T) if not found.</returns>
|
||||
public virtual T GetValue(object data)
|
||||
{
|
||||
return this.TryGetValue(data).Value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// try to Get the value.
|
||||
/// </summary>
|
||||
/// <param name="data">data to use for expression binding.</param>
|
||||
/// <returns>value.</returns>
|
||||
public virtual (T Value, string Error) TryGetValue(object data)
|
||||
{
|
||||
if (Expression != null)
|
||||
{
|
||||
return Expression.TryEvaluate<T>(data);
|
||||
}
|
||||
|
||||
return (Value, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the value.
|
||||
/// </summary>
|
||||
/// <param name="value">value to set.</param>
|
||||
public virtual void SetValue(object value)
|
||||
{
|
||||
this.Value = default(T);
|
||||
this.Expression = null;
|
||||
|
||||
if (value == null)
|
||||
{
|
||||
this.Value = default(T);
|
||||
this.Expression = null;
|
||||
return;
|
||||
}
|
||||
|
||||
if (value is string stringOrExpression)
|
||||
{
|
||||
Expression = new ExpressionEngine().Parse(stringOrExpression.TrimStart('='));
|
||||
return;
|
||||
}
|
||||
|
||||
this.Value = ConvertObject(value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert raw object to desired value type.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This method is called whenever an object is fected via expression or is deserialized from raw text.
|
||||
/// </remarks>
|
||||
/// <param name="result">result to convert to object of type T.</param>
|
||||
/// <returns>object of type T.</returns>
|
||||
protected virtual T ConvertObject(object result)
|
||||
{
|
||||
if (result is T)
|
||||
{
|
||||
return (T)result;
|
||||
}
|
||||
|
||||
if (result == null)
|
||||
{
|
||||
return default(T);
|
||||
}
|
||||
|
||||
return JToken.FromObject(result).ToObject<T>();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
using Microsoft.Bot.Builder.Dialogs.Adaptive.Converters;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Microsoft.Bot.Builder.Dialogs.Adaptive
|
||||
{
|
||||
/// <summary>
|
||||
/// IntExpression - represents a property which is either an Integer or a string expression which resolves to a Integer.
|
||||
/// </summary>
|
||||
/// <remarks>String values are always interpreted as an expression, whether it has '=' prefix or not.</remarks>
|
||||
[JsonConverter(typeof(IntExpressionConverter))]
|
||||
public class IntExpression : ExpressionProperty<int>
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="IntExpression"/> class.
|
||||
/// </summary>
|
||||
public IntExpression()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="IntExpression"/> class.
|
||||
/// </summary>
|
||||
/// <param name="value">value to return.</param>
|
||||
public IntExpression(int value)
|
||||
: base(value)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="IntExpression"/> class.
|
||||
/// </summary>
|
||||
/// <param name="expression">string expression to resolve to an int.</param>
|
||||
public IntExpression(string expression)
|
||||
: base(expression)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="IntExpression"/> class.
|
||||
/// </summary>
|
||||
/// <param name="value">JToken to resolve to an int.</param>
|
||||
public IntExpression(JToken value)
|
||||
: base(value)
|
||||
{
|
||||
}
|
||||
|
||||
public static implicit operator IntExpression(int value) => new IntExpression(value);
|
||||
|
||||
public static implicit operator IntExpression(string value) => new IntExpression(value);
|
||||
|
||||
public static implicit operator IntExpression(JToken value) => new IntExpression(value);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
using Microsoft.Bot.Builder.Dialogs.Adaptive.Converters;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Microsoft.Bot.Builder.Dialogs.Adaptive
|
||||
{
|
||||
/// <summary>
|
||||
/// NumberExpression - represents a property which is either a float or a string expression which resolves to a float.
|
||||
/// </summary>
|
||||
/// <remarks>String values are always interpreted as an expression, whether it has '=' prefix or not.</remarks>
|
||||
[JsonConverter(typeof(NumberExpressionConverter))]
|
||||
public class NumberExpression : ExpressionProperty<float>
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="NumberExpression"/> class.
|
||||
/// </summary>
|
||||
public NumberExpression()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="NumberExpression"/> class.
|
||||
/// </summary>
|
||||
/// <param name="value">value to use.</param>
|
||||
public NumberExpression(float value)
|
||||
: base(value)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="NumberExpression"/> class.
|
||||
/// </summary>
|
||||
/// <param name="expression">string to interpret as expression or number.</param>
|
||||
public NumberExpression(string expression)
|
||||
: base(expression)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="NumberExpression"/> class.
|
||||
/// </summary>
|
||||
/// <param name="value">jtoken to interpret as expression or number.</param>
|
||||
public NumberExpression(JToken value)
|
||||
: base(value)
|
||||
{
|
||||
}
|
||||
|
||||
public static implicit operator NumberExpression(float value) => new NumberExpression(value);
|
||||
|
||||
public static implicit operator NumberExpression(string value) => new NumberExpression(value);
|
||||
|
||||
public static implicit operator NumberExpression(JToken value) => new NumberExpression(value);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
using Microsoft.Bot.Builder.Dialogs.Adaptive.Converters;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Microsoft.Bot.Builder.Dialogs.Adaptive
|
||||
{
|
||||
/// <summary>
|
||||
/// ObjectExpression(T) - represents a property which is either an object of type T or a string expression which resolves to a object of type T.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">the type of object.</typeparam>
|
||||
/// <remarks>String values are always interpreted as an expression, whether it has '=' prefix or not.</remarks>
|
||||
public class ObjectExpression<T> : ExpressionProperty<T>
|
||||
{
|
||||
public ObjectExpression()
|
||||
{
|
||||
}
|
||||
|
||||
public ObjectExpression(T value)
|
||||
: base(value)
|
||||
{
|
||||
}
|
||||
|
||||
public ObjectExpression(string expressionOrString)
|
||||
: base(expressionOrString)
|
||||
{
|
||||
}
|
||||
|
||||
public ObjectExpression(JToken value)
|
||||
: base(value)
|
||||
{
|
||||
}
|
||||
|
||||
public static implicit operator ObjectExpression<T>(T value) => new ObjectExpression<T>(value);
|
||||
|
||||
public static implicit operator ObjectExpression<T>(string value) => new ObjectExpression<T>(value);
|
||||
|
||||
public static implicit operator ObjectExpression<T>(JToken value) => new ObjectExpression<T>(value);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
using Microsoft.Bot.Builder.Dialogs.Adaptive.Converters;
|
||||
using Microsoft.Bot.Builder.LanguageGeneration;
|
||||
using Microsoft.Bot.Expressions;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Microsoft.Bot.Builder.Dialogs.Adaptive
|
||||
{
|
||||
/// <summary>
|
||||
/// StringExpression - represents a property which is either a string value or a string expression.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// If the value is
|
||||
/// * a string with '=' prefix then the string is treated as an expression to resolve to a string.
|
||||
/// * a string without '=' then value is treated as string with string interpolation.
|
||||
/// * You can escape the '=' prefix by putting a backslash.
|
||||
/// Examples:
|
||||
/// prop = "Hello @{user.name}" => "Hello Joe"
|
||||
/// prop = "=length(user.name)" => "3"
|
||||
/// prop = "=user.name" => "Joe"
|
||||
/// prop = "\=user" => "=user".
|
||||
/// </remarks>
|
||||
[JsonConverter(typeof(StringExpressionConverter))]
|
||||
public class StringExpression : ExpressionProperty<string>
|
||||
{
|
||||
private LGFile lg = new LGFile();
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="StringExpression"/> class.
|
||||
/// </summary>
|
||||
public StringExpression()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="StringExpression"/> class.
|
||||
/// </summary>
|
||||
/// <param name="valueOrExpression">string to interpret as string or expression to a string.</param>
|
||||
public StringExpression(string valueOrExpression)
|
||||
: base(valueOrExpression)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="StringExpression"/> class.
|
||||
/// </summary>
|
||||
/// <param name="value">value to interpret as a string or expression to a string.</param>
|
||||
public StringExpression(JToken value)
|
||||
: base(value)
|
||||
{
|
||||
}
|
||||
|
||||
public static implicit operator StringExpression(string valueOrExpression) => new StringExpression(valueOrExpression);
|
||||
|
||||
public static implicit operator StringExpression(JToken value) => new StringExpression(value);
|
||||
|
||||
public override (string Value, string Error) TryGetValue(object data)
|
||||
{
|
||||
if (this.Value != null)
|
||||
{
|
||||
// interpolated string
|
||||
return (lg.Evaluate(this.Value, data).ToString(), null);
|
||||
}
|
||||
|
||||
return base.TryGetValue(data);
|
||||
}
|
||||
|
||||
public override void SetValue(object value)
|
||||
{
|
||||
var stringOrExpression = (value as string) ?? (value as JValue)?.Value as string;
|
||||
|
||||
if (stringOrExpression != null)
|
||||
{
|
||||
// if it starts with = it always is an expression
|
||||
if (stringOrExpression.StartsWith("="))
|
||||
{
|
||||
Expression = new ExpressionEngine().Parse(stringOrExpression.TrimStart('='));
|
||||
return;
|
||||
}
|
||||
else if (stringOrExpression.StartsWith("\\="))
|
||||
{
|
||||
// then trim off the escape char for equals (\=foo) should simply be the string (=foo), and not an expression (but it could still be stringTemplate)
|
||||
stringOrExpression = stringOrExpression.TrimStart('\\');
|
||||
}
|
||||
|
||||
this.Value = stringOrExpression;
|
||||
return;
|
||||
}
|
||||
|
||||
base.SetValue(value);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,89 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
using Microsoft.Bot.Builder.Dialogs.Adaptive.Converters;
|
||||
using Microsoft.Bot.Builder.LanguageGeneration;
|
||||
using Microsoft.Bot.Expressions;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Microsoft.Bot.Builder.Dialogs.Adaptive
|
||||
{
|
||||
/// <summary>
|
||||
/// ValueExpression - represents a property which is an object of any kind or a string expression.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// If the value is
|
||||
/// * a string with '=' prefix then the string is treated as an expression to resolve to a string.
|
||||
/// * a string without '=' then value is treated as string with string interpolation.
|
||||
/// * any other type, then it is of that type (int, bool, object, etc.)
|
||||
/// You can escape the '=' prefix by putting a backslash.
|
||||
/// Examples:
|
||||
/// prop = true ==> true
|
||||
/// prop = "Hello @{user.name}" => "Hello Joe"
|
||||
/// prop = "=length(user.name)" => 3
|
||||
/// prop = "=user.age" => 45.
|
||||
/// prop = "\=user.age" => "=user.age".
|
||||
/// </remarks>
|
||||
[JsonConverter(typeof(ValueExpressionConverter))]
|
||||
public class ValueExpression : ExpressionProperty<object>
|
||||
{
|
||||
private LGFile lg = new LGFile();
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ValueExpression"/> class.
|
||||
/// </summary>
|
||||
public ValueExpression()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ValueExpression"/> class.
|
||||
/// </summary>
|
||||
/// <param name="value">value to interpret as object or string expression.</param>
|
||||
public ValueExpression(object value)
|
||||
: base(value)
|
||||
{
|
||||
}
|
||||
|
||||
public static implicit operator ValueExpression(string valueOrExpression) => new ValueExpression(valueOrExpression);
|
||||
|
||||
public static implicit operator ValueExpression(JToken value) => new ValueExpression(value);
|
||||
|
||||
public override (object Value, string Error) TryGetValue(object data)
|
||||
{
|
||||
if (this.Value != null && this.Value is string val)
|
||||
{
|
||||
// value is a string (not an expression) should be interpreted as string, which means interperlated
|
||||
return (lg.Evaluate(val, data).ToString(), null);
|
||||
}
|
||||
|
||||
return base.TryGetValue(data);
|
||||
}
|
||||
|
||||
public override void SetValue(object value)
|
||||
{
|
||||
var stringOrExpression = (value as string) ?? (value as JValue)?.Value as string;
|
||||
|
||||
if (stringOrExpression != null)
|
||||
{
|
||||
// if it starts with = it always is an expression
|
||||
if (stringOrExpression.StartsWith("="))
|
||||
{
|
||||
Expression = new ExpressionEngine().Parse(stringOrExpression.TrimStart('='));
|
||||
return;
|
||||
}
|
||||
else if (stringOrExpression.StartsWith("\\="))
|
||||
{
|
||||
// then trim off the escape char for equals (\=foo) should simply be the string (=foo), and not an expression (but it could still be stringTemplate)
|
||||
stringOrExpression = stringOrExpression.TrimStart('\\');
|
||||
}
|
||||
|
||||
this.Value = stringOrExpression;
|
||||
return;
|
||||
}
|
||||
|
||||
base.SetValue(value);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,6 +2,8 @@
|
|||
// Licensed under the MIT License.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Bot.Builder.Dialogs.Adaptive;
|
||||
using Microsoft.Bot.Builder.Dialogs.Adaptive.Converters;
|
||||
using Microsoft.Bot.Builder.Dialogs.Adaptive.QnA;
|
||||
using Microsoft.Bot.Builder.Dialogs.Adaptive.QnA.Recognizers;
|
||||
using Microsoft.Bot.Builder.Dialogs.Debugging;
|
||||
|
@ -24,6 +26,8 @@ namespace Microsoft.Bot.Builder.AI.QnA
|
|||
|
||||
public override IEnumerable<JsonConverter> GetConverters(ISourceMap sourceMap, IRefResolver refResolver, Stack<string> paths)
|
||||
{
|
||||
yield return new ArrayExpressionConverter<Metadata>();
|
||||
|
||||
yield break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,10 +14,6 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.QnA
|
|||
[JsonProperty("$kind")]
|
||||
public const string DeclarativeType = "Microsoft.QnAMakerDialog";
|
||||
|
||||
private Expression knowledgebaseIdExpression;
|
||||
private Expression endpointkeyExpression;
|
||||
private Expression hostnameExpression;
|
||||
|
||||
[JsonConstructor]
|
||||
public QnAMakerDialog2([CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0)
|
||||
: base(sourceFilePath, sourceLineNumber)
|
||||
|
@ -31,11 +27,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.QnA
|
|||
/// The knowledgebase Id.
|
||||
/// </value>
|
||||
[JsonProperty("knowledgeBaseId")]
|
||||
public string KnowledgeBaseId
|
||||
{
|
||||
get { return knowledgebaseIdExpression?.ToString(); }
|
||||
set { knowledgebaseIdExpression = value != null ? new ExpressionEngine().Parse(value) : null; }
|
||||
}
|
||||
public StringExpression KnowledgeBaseId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Hostname for your QnA Maker service.
|
||||
|
@ -44,11 +36,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.QnA
|
|||
/// The host name of the QnA Maker knowledgebase.
|
||||
/// </value>
|
||||
[JsonProperty("hostname")]
|
||||
public string HostName
|
||||
{
|
||||
get { return hostnameExpression?.ToString(); }
|
||||
set { hostnameExpression = value != null ? new ExpressionEngine().Parse(value) : null; }
|
||||
}
|
||||
public StringExpression HostName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Endpoint key for the QnA Maker KB.
|
||||
|
@ -57,11 +45,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.QnA
|
|||
/// The endpoint key for the QnA service.
|
||||
/// </value>
|
||||
[JsonProperty("endpointKey")]
|
||||
public string EndpointKey
|
||||
{
|
||||
get { return endpointkeyExpression?.ToString(); }
|
||||
set { endpointkeyExpression = value != null ? new ExpressionEngine().Parse(value) : null; }
|
||||
}
|
||||
public StringExpression EndpointKey { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Threshold score to filter results.
|
||||
|
@ -70,7 +54,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.QnA
|
|||
/// The threshold for the results.
|
||||
/// </value>
|
||||
[JsonProperty("threshold")]
|
||||
public float Threshold { get; set; } = DefaultThreshold;
|
||||
public NumberExpression Threshold { get; set; } = DefaultThreshold;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the number of results you want.
|
||||
|
@ -79,7 +63,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.QnA
|
|||
/// The number of results you want.
|
||||
/// </value>
|
||||
[JsonProperty("top")]
|
||||
public int Top { get; set; } = DefaultTopN;
|
||||
public IntExpression Top { get; set; } = DefaultTopN;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the template for Default answer to return when none found in KB.
|
||||
|
@ -97,7 +81,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.QnA
|
|||
/// Title for active learning suggestions card.
|
||||
/// </value>
|
||||
[JsonProperty("activeLearningCardTitle")]
|
||||
public string ActiveLearningCardTitle { get; set; }
|
||||
public StringExpression ActiveLearningCardTitle { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Text for no match option.
|
||||
|
@ -106,7 +90,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.QnA
|
|||
/// The Text for no match option.
|
||||
/// </value>
|
||||
[JsonProperty("cardNoMatchText")]
|
||||
public string CardNoMatchText { get; set; }
|
||||
public StringExpression CardNoMatchText { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the template for Custom response when no match option was selected.
|
||||
|
@ -124,7 +108,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.QnA
|
|||
/// The metadata strict filters.
|
||||
/// </value>
|
||||
[JsonProperty("strictFilters")]
|
||||
public Metadata[] StrictFilters { get; set; }
|
||||
public ArrayExpression<Metadata> StrictFilters { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether gets or sets environment of knowledgebase to be called.
|
||||
|
@ -142,10 +126,12 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.QnA
|
|||
/// Ranker Types.
|
||||
/// </value>
|
||||
[JsonProperty("rankerType")]
|
||||
public string RankerType { get; set; } = RankerTypes.DefaultRankerType;
|
||||
public StringExpression RankerType { get; set; } = new StringExpression(RankerTypes.DefaultRankerType);
|
||||
|
||||
protected async override Task<IQnAMakerClient> GetQnAMakerClientAsync(DialogContext dc)
|
||||
{
|
||||
var dcState = dc.GetState();
|
||||
|
||||
var qnaClient = dc.Context.TurnState.Get<IQnAMakerClient>();
|
||||
if (qnaClient != null)
|
||||
{
|
||||
|
@ -153,9 +139,9 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.QnA
|
|||
return qnaClient;
|
||||
}
|
||||
|
||||
var (epKey, error) = this.endpointkeyExpression.TryEvaluate(dc.GetState());
|
||||
var (hn, error2) = this.hostnameExpression.TryEvaluate(dc.GetState());
|
||||
var (kbId, error3) = this.knowledgebaseIdExpression.TryEvaluate(dc.GetState());
|
||||
var (epKey, error) = this.EndpointKey.TryGetValue(dcState);
|
||||
var (hn, error2) = this.HostName.TryGetValue(dcState);
|
||||
var (kbId, error3) = this.KnowledgeBaseId.TryGetValue(dcState);
|
||||
|
||||
var endpoint = new QnAMakerEndpoint
|
||||
{
|
||||
|
@ -169,26 +155,29 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.QnA
|
|||
|
||||
protected override Task<QnAMakerOptions> GetQnAMakerOptionsAsync(DialogContext dc)
|
||||
{
|
||||
var dcState = dc.GetState();
|
||||
|
||||
return Task.FromResult(new QnAMakerOptions
|
||||
{
|
||||
ScoreThreshold = this.Threshold,
|
||||
StrictFilters = this.StrictFilters,
|
||||
Top = this.Top,
|
||||
ScoreThreshold = this.Threshold.GetValue(dcState),
|
||||
StrictFilters = this.StrictFilters?.GetValue(dcState)?.ToArray(),
|
||||
Top = this.Top.GetValue(dcState),
|
||||
QnAId = 0,
|
||||
RankerType = this.RankerType,
|
||||
RankerType = this.RankerType.GetValue(dcState),
|
||||
IsTest = this.IsTest
|
||||
});
|
||||
}
|
||||
|
||||
protected async override Task<QnADialogResponseOptions> GetQnAResponseOptionsAsync(DialogContext dc)
|
||||
{
|
||||
var noAnswer = (this.NoAnswer != null) ? await this.NoAnswer.BindToData(dc.Context, dc.GetState()).ConfigureAwait(false) : null;
|
||||
var cardNoMatchResponse = (this.CardNoMatchResponse != null) ? await this.CardNoMatchResponse.BindToData(dc.Context, dc.GetState()).ConfigureAwait(false) : null;
|
||||
var dcState = dc.GetState();
|
||||
var noAnswer = (this.NoAnswer != null) ? await this.NoAnswer.BindToData(dc.Context, dcState).ConfigureAwait(false) : null;
|
||||
var cardNoMatchResponse = (this.CardNoMatchResponse != null) ? await this.CardNoMatchResponse.BindToData(dc.Context, dcState).ConfigureAwait(false) : null;
|
||||
|
||||
var responseOptions = new QnADialogResponseOptions
|
||||
{
|
||||
ActiveLearningCardTitle = this.ActiveLearningCardTitle,
|
||||
CardNoMatchText = this.CardNoMatchText,
|
||||
ActiveLearningCardTitle = this.ActiveLearningCardTitle.GetValue(dcState),
|
||||
CardNoMatchText = this.CardNoMatchText.GetValue(dcState),
|
||||
NoAnswer = noAnswer,
|
||||
CardNoMatchResponse = cardNoMatchResponse,
|
||||
};
|
||||
|
|
|
@ -6,13 +6,9 @@ using System.Collections.Generic;
|
|||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Bot.Builder.AI.QnA;
|
||||
using Microsoft.Bot.Expressions;
|
||||
using Microsoft.Bot.Schema;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
|
@ -30,10 +26,6 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.QnA.Recognizers
|
|||
|
||||
private const string IntentPrefix = "intent=";
|
||||
|
||||
private Expression knowledgebaseIdExpression;
|
||||
private Expression endpointkeyExpression;
|
||||
private Expression hostnameExpression;
|
||||
|
||||
public QnAMakerRecognizer()
|
||||
{
|
||||
}
|
||||
|
@ -45,11 +37,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.QnA.Recognizers
|
|||
/// The knowledgebase Id.
|
||||
/// </value>
|
||||
[JsonProperty("knowledgeBaseId")]
|
||||
public string KnowledgeBaseId
|
||||
{
|
||||
get { return knowledgebaseIdExpression?.ToString(); }
|
||||
set { knowledgebaseIdExpression = value != null ? new ExpressionEngine().Parse(value) : null; }
|
||||
}
|
||||
public StringExpression KnowledgeBaseId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Hostname for your QnA Maker service.
|
||||
|
@ -58,11 +46,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.QnA.Recognizers
|
|||
/// The host name of the QnA Maker knowledgebase.
|
||||
/// </value>
|
||||
[JsonProperty("hostname")]
|
||||
public string HostName
|
||||
{
|
||||
get { return hostnameExpression?.ToString(); }
|
||||
set { hostnameExpression = value != null ? new ExpressionEngine().Parse(value) : null; }
|
||||
}
|
||||
public StringExpression HostName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Endpoint key for the QnA Maker KB.
|
||||
|
@ -71,11 +55,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.QnA.Recognizers
|
|||
/// The endpoint key for the QnA service.
|
||||
/// </value>
|
||||
[JsonProperty("endpointKey")]
|
||||
public string EndpointKey
|
||||
{
|
||||
get { return endpointkeyExpression?.ToString(); }
|
||||
set { endpointkeyExpression = value != null ? new ExpressionEngine().Parse(value) : null; }
|
||||
}
|
||||
public StringExpression EndpointKey { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the number of results you want.
|
||||
|
@ -85,7 +65,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.QnA.Recognizers
|
|||
/// </value>
|
||||
[DefaultValue(3)]
|
||||
[JsonProperty("top")]
|
||||
public int Top { get; set; } = 3;
|
||||
public IntExpression Top { get; set; } = 3;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the threshold score to filter results.
|
||||
|
@ -95,7 +75,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.QnA.Recognizers
|
|||
/// </value>
|
||||
[DefaultValue(0.3F)]
|
||||
[JsonProperty("threshold")]
|
||||
public float Threshold { get; set; } = 0.3F;
|
||||
public NumberExpression Threshold { get; set; } = 0.3F;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether gets or sets environment of knowledgebase to be called.
|
||||
|
@ -113,13 +93,15 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.QnA.Recognizers
|
|||
/// The desired RankerType.
|
||||
/// </value>
|
||||
[JsonProperty("rankerType")]
|
||||
public string RankerType { get; set; } = RankerTypes.DefaultRankerType;
|
||||
public StringExpression RankerType { get; set; } = RankerTypes.DefaultRankerType;
|
||||
|
||||
[JsonIgnore]
|
||||
public HttpClient HttpClient { get; set; }
|
||||
|
||||
public override async Task<RecognizerResult> RecognizeAsync(DialogContext dialogContext, string text, string locale, CancellationToken cancellationToken)
|
||||
{
|
||||
var dcState = dialogContext.GetState();
|
||||
|
||||
// Identify matched intents
|
||||
var utterance = text ?? string.Empty;
|
||||
|
||||
|
@ -135,7 +117,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.QnA.Recognizers
|
|||
};
|
||||
|
||||
// if there is $qna.metadata set add to filters
|
||||
var externalMetadata = dialogContext.GetState().GetValue<Metadata[]>("$qna.metadata");
|
||||
var externalMetadata = dcState.GetValue<Metadata[]>("$qna.metadata");
|
||||
if (externalMetadata != null)
|
||||
{
|
||||
filters.AddRange(externalMetadata);
|
||||
|
@ -147,12 +129,12 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.QnA.Recognizers
|
|||
dialogContext.Context,
|
||||
new QnAMakerOptions
|
||||
{
|
||||
Context = dialogContext.GetState().GetValue<QnARequestContext>("$qna.context"),
|
||||
ScoreThreshold = this.Threshold,
|
||||
Context = dcState.GetValue<QnARequestContext>("$qna.context"),
|
||||
ScoreThreshold = this.Threshold.TryGetValue(dcState).Value,
|
||||
StrictFilters = filters.ToArray(),
|
||||
Top = this.Top,
|
||||
Top = this.Top.TryGetValue(dcState).Value,
|
||||
QnAId = 0,
|
||||
RankerType = this.RankerType,
|
||||
RankerType = this.RankerType.TryGetValue(dcState).Value,
|
||||
IsTest = this.IsTest
|
||||
},
|
||||
null).ConfigureAwait(false);
|
||||
|
@ -204,9 +186,11 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.QnA.Recognizers
|
|||
return Task.FromResult(qnaClient);
|
||||
}
|
||||
|
||||
var (epKey, error) = this.endpointkeyExpression.TryEvaluate(dc.GetState());
|
||||
var (hn, error2) = this.hostnameExpression.TryEvaluate(dc.GetState());
|
||||
var (kbId, error3) = this.knowledgebaseIdExpression.TryEvaluate(dc.GetState());
|
||||
var dcState = dc.GetState();
|
||||
|
||||
var (epKey, error) = this.EndpointKey.TryGetValue(dcState);
|
||||
var (hn, error2) = this.HostName.TryGetValue(dcState);
|
||||
var (kbId, error3) = this.KnowledgeBaseId.TryGetValue(dcState);
|
||||
|
||||
var endpoint = new QnAMakerEndpoint
|
||||
{
|
||||
|
|
|
@ -50,7 +50,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Recognizers
|
|||
set
|
||||
{
|
||||
this.pattern = value;
|
||||
this.regex = new Regex(pattern, RegexOptions.Compiled);
|
||||
this.regex = new Regex(pattern, RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ using System.Linq;
|
|||
using System.Text.RegularExpressions;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Bot.Builder.TraceExtensions;
|
||||
using Microsoft.Bot.Schema;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
@ -50,7 +51,7 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Recognizers
|
|||
// Identify matched intents
|
||||
text = text ?? string.Empty;
|
||||
|
||||
var result = new RecognizerResult()
|
||||
var recognizerResult = new RecognizerResult()
|
||||
{
|
||||
Text = text,
|
||||
Intents = new Dictionary<string, IntentScore>(),
|
||||
|
@ -74,9 +75,13 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Recognizers
|
|||
{
|
||||
// TODO length weighted match and multiple intents
|
||||
var intentKey = intentPattern.Intent.Replace(" ", "_");
|
||||
if (!result.Intents.ContainsKey(intentKey))
|
||||
if (!recognizerResult.Intents.ContainsKey(intentKey))
|
||||
{
|
||||
result.Intents.Add(intentKey, new IntentScore() { Score = 1.0 });
|
||||
recognizerResult.Intents.Add(intentKey, new IntentScore()
|
||||
{
|
||||
Score = 1.0,
|
||||
Properties = new Dictionary<string, object>() { { "pattern", intentPattern.Pattern } }
|
||||
});
|
||||
}
|
||||
|
||||
// Check for named capture groups
|
||||
|
@ -115,16 +120,16 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Recognizers
|
|||
}
|
||||
|
||||
// map entityPool of Entity objects => RecognizerResult entity format
|
||||
result.Entities = new JObject();
|
||||
recognizerResult.Entities = new JObject();
|
||||
|
||||
foreach (var entityResult in entityPool)
|
||||
{
|
||||
// add value
|
||||
JToken values;
|
||||
if (!result.Entities.TryGetValue(entityResult.Type, StringComparison.OrdinalIgnoreCase, out values))
|
||||
if (!recognizerResult.Entities.TryGetValue(entityResult.Type, StringComparison.OrdinalIgnoreCase, out values))
|
||||
{
|
||||
values = new JArray();
|
||||
result.Entities[entityResult.Type] = values;
|
||||
recognizerResult.Entities[entityResult.Type] = values;
|
||||
}
|
||||
|
||||
// The Entity type names are not consistent, map everything to camelcase so we can process them cleaner.
|
||||
|
@ -133,10 +138,10 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Recognizers
|
|||
|
||||
// get/create $instance
|
||||
JToken instanceRoot;
|
||||
if (!result.Entities.TryGetValue("$instance", StringComparison.OrdinalIgnoreCase, out instanceRoot))
|
||||
if (!recognizerResult.Entities.TryGetValue("$instance", StringComparison.OrdinalIgnoreCase, out instanceRoot))
|
||||
{
|
||||
instanceRoot = new JObject();
|
||||
result.Entities["$instance"] = instanceRoot;
|
||||
recognizerResult.Entities["$instance"] = instanceRoot;
|
||||
}
|
||||
|
||||
// add instanceData
|
||||
|
@ -158,12 +163,14 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Recognizers
|
|||
}
|
||||
|
||||
// if no match return None intent
|
||||
if (!result.Intents.Keys.Any())
|
||||
if (!recognizerResult.Intents.Keys.Any())
|
||||
{
|
||||
result.Intents.Add("None", new IntentScore() { Score = 1.0 });
|
||||
recognizerResult.Intents.Add("None", new IntentScore() { Score = 1.0 });
|
||||
}
|
||||
|
||||
return result;
|
||||
await dialogContext.Context.TraceActivityAsync(nameof(RegexRecognizer), JObject.FromObject(recognizerResult), "RecognizerResult", "Regex RecognizerResult", cancellationToken).ConfigureAwait(false);
|
||||
|
||||
return recognizerResult;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
},
|
||||
"disabled": {
|
||||
"$role": "expression",
|
||||
"type": [ "boolean", "string"],
|
||||
"title": "Disabled",
|
||||
"description": "Optional condition which if true will disable this action.",
|
||||
"examples": [
|
||||
|
@ -20,6 +21,8 @@
|
|||
},
|
||||
"dialog": {
|
||||
"$kind": "Microsoft.IDialog",
|
||||
"$role": "expression",
|
||||
"type": ["string", "object"],
|
||||
"title": "Dialog name",
|
||||
"description": "Name of the dialog to call.",
|
||||
"examples": [
|
||||
|
@ -27,7 +30,8 @@
|
|||
]
|
||||
},
|
||||
"options": {
|
||||
"type": "object",
|
||||
"$role": "expression",
|
||||
"type": [ "string", "object" ],
|
||||
"title": "Options",
|
||||
"description": "One or more options that are passed to the dialog that is called.",
|
||||
"additionalProperties": {
|
||||
|
@ -36,13 +40,15 @@
|
|||
}
|
||||
},
|
||||
"activityProcessed": {
|
||||
"type": "boolean",
|
||||
"$role": "expression",
|
||||
"type": [ "boolean", "string" ],
|
||||
"title": "Activity Processed",
|
||||
"description": "When set to false, the dialog that is called can process the current activity.",
|
||||
"default": true
|
||||
},
|
||||
"resultProperty": {
|
||||
"$role": "expression",
|
||||
"type": "string",
|
||||
"title": "Property",
|
||||
"description": "Property to store any value returned by the dialog that is called.",
|
||||
"examples": [
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
},
|
||||
"disabled": {
|
||||
"$role": "expression",
|
||||
"type": [ "boolean", "string" ],
|
||||
"title": "Disabled",
|
||||
"description": "Optional condition which if true will disable this action.",
|
||||
"examples": [
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
},
|
||||
"disabled": {
|
||||
"$role": "expression",
|
||||
"type": [ "boolean", "string" ],
|
||||
"title": "Disabled",
|
||||
"description": "Optional condition which if true will disable this action.",
|
||||
"examples": [
|
||||
|
@ -19,12 +20,14 @@
|
|||
]
|
||||
},
|
||||
"eventName": {
|
||||
"$role": "expression",
|
||||
"type": "string",
|
||||
"title": "Event name",
|
||||
"description": "Name of the event to emit.",
|
||||
"type": "string"
|
||||
"description": "Name of the event to emit."
|
||||
},
|
||||
"eventValue": {
|
||||
"type": "object",
|
||||
"$role": "expression",
|
||||
"type": [ "object", "array", "number", "integer", "boolean", "string" ],
|
||||
"title": "Event value",
|
||||
"description": "Value to emit with the event (optional).",
|
||||
"additionalProperties": true
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
},
|
||||
"disabled": {
|
||||
"$role": "expression",
|
||||
"type": [ "boolean", "string" ],
|
||||
"title": "Disabled",
|
||||
"description": "Optional condition which if true will disable this action.",
|
||||
"examples": [
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
},
|
||||
"disabled": {
|
||||
"$role": "expression",
|
||||
"type": [ "boolean", "string" ],
|
||||
"title": "Disabled",
|
||||
"description": "Optional condition which if true will disable this action.",
|
||||
"examples": [
|
||||
|
|
|
@ -16,14 +16,16 @@
|
|||
},
|
||||
"activityId": {
|
||||
"$role": "expression",
|
||||
"type": "string",
|
||||
"title": "ActivityId",
|
||||
"description": "expression to an activityId to delete",
|
||||
"examples": [
|
||||
"$lastActivity"
|
||||
"=$lastActivity"
|
||||
]
|
||||
},
|
||||
"disabled": {
|
||||
"$role": "expression",
|
||||
"type": [ "boolean", "string" ],
|
||||
"title": "Disabled",
|
||||
"description": "Optional condition which if true will disable this action.",
|
||||
"examples": [
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
},
|
||||
"disabled": {
|
||||
"$role": "expression",
|
||||
"type": [ "boolean", "string" ],
|
||||
"title": "Disabled",
|
||||
"description": "Optional condition which if true will disable this action.",
|
||||
"examples": [
|
||||
|
@ -27,6 +28,7 @@
|
|||
"description": "Properties to delete.",
|
||||
"items": {
|
||||
"$role": "expression",
|
||||
"type": "string",
|
||||
"title": "Property",
|
||||
"description": "Property to delete."
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
},
|
||||
"disabled": {
|
||||
"$role": "expression",
|
||||
"type": [ "boolean", "string" ],
|
||||
"title": "Disabled",
|
||||
"description": "Optional condition which if true will disable this action.",
|
||||
"examples": [
|
||||
|
@ -23,6 +24,7 @@
|
|||
},
|
||||
"property": {
|
||||
"$role": "expression",
|
||||
"type": "string",
|
||||
"title": "Property",
|
||||
"description": "Property to delete."
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
},
|
||||
"disabled": {
|
||||
"$role": "expression",
|
||||
"type": [ "boolean", "string" ],
|
||||
"title": "Disabled",
|
||||
"description": "Optional condition which if true will disable this action.",
|
||||
"examples": [
|
||||
|
@ -23,6 +24,7 @@
|
|||
]
|
||||
},
|
||||
"changeType": {
|
||||
"$role": "expression",
|
||||
"type": "string",
|
||||
"title": "Type of change",
|
||||
"description": "Type of change to apply to the current actions.",
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
"description": "Optional id for the dialog"
|
||||
},
|
||||
"changeType": {
|
||||
"$role": "expression",
|
||||
"type": "string",
|
||||
"title": "Type of change",
|
||||
"description": "Type of change to the array in memory.",
|
||||
|
@ -28,6 +29,7 @@
|
|||
},
|
||||
"disabled": {
|
||||
"$role": "expression",
|
||||
"type": [ "boolean", "string" ],
|
||||
"title": "Disabled",
|
||||
"description": "Optional condition which if true will disable this action.",
|
||||
"examples": [
|
||||
|
@ -36,16 +38,19 @@
|
|||
},
|
||||
"itemsProperty": {
|
||||
"$role": "expression",
|
||||
"type": "string",
|
||||
"title": "Items property",
|
||||
"description": "Property that holds the array to update."
|
||||
},
|
||||
"resultProperty": {
|
||||
"$role": "expression",
|
||||
"type": "string",
|
||||
"title": "Result Property",
|
||||
"description": "Property to store the result of this action."
|
||||
},
|
||||
"value": {
|
||||
"$role": "expression",
|
||||
"type": [ "object", "array", "number", "integer", "boolean", "string" ],
|
||||
"title": "Value",
|
||||
"description": "New value or expression.",
|
||||
"examples": [
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
},
|
||||
"disabled": {
|
||||
"$role": "expression",
|
||||
"type": [ "boolean", "string" ],
|
||||
"title": "Disabled",
|
||||
"description": "Optional condition which if true will disable this action.",
|
||||
"examples": [
|
||||
|
@ -22,10 +23,10 @@
|
|||
]
|
||||
},
|
||||
"eventName": {
|
||||
"$role": "expression",
|
||||
"type": "string",
|
||||
"title": "Event name",
|
||||
"description": "Name of the event to emit.",
|
||||
"anyOf": [
|
||||
{
|
||||
"enum": [
|
||||
"beginDialog",
|
||||
"resumeDialog",
|
||||
|
@ -41,18 +42,15 @@
|
|||
"actionsResumed"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
"eventValue": {
|
||||
"$role": "expression",
|
||||
"type": [ "object", "array", "number", "integer", "boolean", "string" ],
|
||||
"title": "Event value",
|
||||
"description": "Value to emit with the event (optional)."
|
||||
},
|
||||
"bubbleEvent": {
|
||||
"type": "boolean",
|
||||
"$role": "expression",
|
||||
"type": [ "boolean", "string" ],
|
||||
"title": "Bubble event",
|
||||
"description": "If true this event is passed on to parent dialogs.",
|
||||
"default": false
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче