├── CODE_OF_CONDUCT.md ├── GPTVirtualAssistant.sln ├── GPTVirtualAssistant ├── .deployment ├── .gitignore ├── Controllers │ ├── BotController.cs │ └── SkillController.cs ├── GPTVirtualAssistant.botproj ├── GPTVirtualAssistant.csproj ├── GPTVirtualAssistant.dialog ├── Nuget.config ├── Program.cs ├── README.md ├── Startup.cs ├── dialogs │ └── emptyBot │ │ └── knowledge-base │ │ └── en-us │ │ └── emptyBot.en-us.qna ├── knowledge-base │ └── en-us │ │ └── GPTVirtualAssistant.en-us.qna ├── language-generation │ └── en-us │ │ ├── GPTVirtualAssistant.en-us.lg │ │ └── common.en-us.lg ├── language-understanding │ └── en-us │ │ └── GPTVirtualAssistant.en-us.lu ├── media │ ├── create-azure-resource-command-line.png │ └── publish-az-login.png ├── recognizers │ ├── GPTVirtualAssistant.en-us.lu.dialog │ ├── GPTVirtualAssistant.lu.dialog │ └── GPTVirtualAssistant.lu.qna.dialog ├── schemas │ ├── sdk.schema │ ├── sdk.uischema │ ├── update-schema.ps1 │ └── update-schema.sh ├── scripts │ ├── DeploymentTemplates │ │ ├── function-template-with-preexisting-rg.json │ │ ├── new-rg-parameters.json │ │ ├── preexisting-rg-parameters.json │ │ ├── qna-template.json │ │ ├── template-with-new-rg.json │ │ └── template-with-preexisting-rg.json │ ├── README.md │ ├── package.json │ └── provisionComposer.js ├── settings │ └── appsettings.example.json └── wwwroot │ └── default.htm ├── LICENSE ├── README.md ├── SECURITY.md ├── SUPPORT.md └── readme_images ├── configure-aoai.png ├── configure-channels.png ├── configure-deployment.png ├── configure-settings.png ├── open-botcomposer.png └── publish-bot.png /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Microsoft Open Source Code of Conduct 2 | 3 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). 4 | 5 | Resources: 6 | 7 | - [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/) 8 | - [Microsoft Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) 9 | - Contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with questions or concerns 10 | -------------------------------------------------------------------------------- /GPTVirtualAssistant.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.30503.244 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GPTVirtualAssistant", "GPTVirtualAssistant\GPTVirtualAssistant.csproj", "{59188C21-2D56-4E8E-B2D2-64BFD955FC6B}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {59188C21-2D56-4E8E-B2D2-64BFD955FC6B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {59188C21-2D56-4E8E-B2D2-64BFD955FC6B}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {59188C21-2D56-4E8E-B2D2-64BFD955FC6B}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {59188C21-2D56-4E8E-B2D2-64BFD955FC6B}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {60EC00FC-40B2-47AF-9965-4389E1EC29F2} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /GPTVirtualAssistant/.deployment: -------------------------------------------------------------------------------- 1 | [config] 2 | project = GPTVirtualAssistant.csproj -------------------------------------------------------------------------------- /GPTVirtualAssistant/.gitignore: -------------------------------------------------------------------------------- 1 | # files generated during the lubuild process 2 | generated/ 3 | 4 | 5 | 6 | 7 | ## Ignore Visual Studio temporary files, build results, and 8 | ## files generated by popular Visual Studio add-ons. 9 | ## 10 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 11 | 12 | # User-specific files 13 | *.suo 14 | *.user 15 | *.userosscache 16 | *.sln.docstates 17 | 18 | # User-specific files (MonoDevelop/Xamarin Studio) 19 | *.userprefs 20 | 21 | # Build results 22 | [Dd]ebug/ 23 | [Dd]ebugPublic/ 24 | [Rr]elease/ 25 | x64/ 26 | x86/ 27 | bld/ 28 | [Bb]in/ 29 | [Oo]bj/ 30 | [Ll]og/ 31 | 32 | # Visual Studio 2015/2017 cache/options directory 33 | .vs/ 34 | # Uncomment if you have tasks that create the project's static files in wwwroot 35 | #wwwroot/ 36 | 37 | # Visual Studio 2017 auto generated files 38 | Generated\ Files/ 39 | 40 | # MSTest test Results 41 | [Tt]est[Rr]esult*/ 42 | [Bb]uild[Ll]og.* 43 | 44 | # NUNIT 45 | *.VisualState.xml 46 | TestResult.xml 47 | 48 | # Build Results of an ATL Project 49 | [Dd]ebugPS/ 50 | [Rr]eleasePS/ 51 | dlldata.c 52 | 53 | # Benchmark Results 54 | BenchmarkDotNet.Artifacts/ 55 | 56 | # .NET Core 57 | project.lock.json 58 | project.fragment.lock.json 59 | artifacts/ 60 | **/Properties/launchSettings.json 61 | 62 | # StyleCop 63 | StyleCopReport.xml 64 | 65 | # Files built by Visual Studio 66 | *_i.c 67 | *_p.c 68 | *_i.h 69 | *.ilk 70 | *.meta 71 | *.obj 72 | *.iobj 73 | *.pch 74 | *.pdb 75 | *.ipdb 76 | *.pgc 77 | *.pgd 78 | *.rsp 79 | *.sbr 80 | *.tlb 81 | *.tli 82 | *.tlh 83 | *.tmp 84 | *.tmp_proj 85 | *.log 86 | *.vspscc 87 | *.vssscc 88 | .builds 89 | *.pidb 90 | *.svclog 91 | *.scc 92 | 93 | # Chutzpah Test files 94 | _Chutzpah* 95 | 96 | # Visual C++ cache files 97 | ipch/ 98 | *.aps 99 | *.ncb 100 | *.opendb 101 | *.opensdf 102 | *.sdf 103 | *.cachefile 104 | *.VC.db 105 | *.VC.VC.opendb 106 | 107 | # Visual Studio profiler 108 | *.psess 109 | *.vsp 110 | *.vspx 111 | *.sap 112 | 113 | # Visual Studio Trace Files 114 | *.e2e 115 | 116 | # TFS 2012 Local Workspace 117 | $tf/ 118 | 119 | # Guidance Automation Toolkit 120 | *.gpState 121 | 122 | # ReSharper is a .NET coding add-in 123 | _ReSharper*/ 124 | *.[Rr]e[Ss]harper 125 | *.DotSettings.user 126 | 127 | # JustCode is a .NET coding add-in 128 | .JustCode 129 | 130 | # TeamCity is a build add-in 131 | _TeamCity* 132 | 133 | # DotCover is a Code Coverage Tool 134 | *.dotCover 135 | 136 | # AxoCover is a Code Coverage Tool 137 | .axoCover/* 138 | !.axoCover/settings.json 139 | 140 | # Visual Studio code coverage results 141 | *.coverage 142 | *.coveragexml 143 | 144 | # NCrunch 145 | _NCrunch_* 146 | .*crunch*.local.xml 147 | nCrunchTemp_* 148 | 149 | # MightyMoose 150 | *.mm.* 151 | AutoTest.Net/ 152 | 153 | # Web workbench (sass) 154 | .sass-cache/ 155 | 156 | # Installshield output folder 157 | [Ee]xpress/ 158 | 159 | # DocProject is a documentation generator add-in 160 | DocProject/buildhelp/ 161 | DocProject/Help/*.HxT 162 | DocProject/Help/*.HxC 163 | DocProject/Help/*.hhc 164 | DocProject/Help/*.hhk 165 | DocProject/Help/*.hhp 166 | DocProject/Help/Html2 167 | DocProject/Help/html 168 | 169 | # Publish Web Output 170 | *.[Pp]ublish.xml 171 | *.azurePubxml 172 | # Note: Comment the next line if you want to checkin your web deploy settings, 173 | # but database connection strings (with potential passwords) will be unencrypted 174 | *.pubxml 175 | *.publishproj 176 | 177 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 178 | # checkin your Azure Web App publish settings, but sensitive information contained 179 | # in these scripts will be unencrypted 180 | PublishScripts/ 181 | 182 | # Uncomment if necessary however generally it will be regenerated when needed 183 | #!**/[Pp]ackages/repositories.config 184 | # NuGet v3's project.json files produces more ignorable files 185 | *.nuget.props 186 | *.nuget.targets 187 | 188 | # Microsoft Azure Build Output 189 | csx/ 190 | *.build.csdef 191 | 192 | # Microsoft Azure Emulator 193 | ecf/ 194 | rcf/ 195 | 196 | # Windows Store app package directories and files 197 | AppPackages/ 198 | BundleArtifacts/ 199 | Package.StoreAssociation.xml 200 | _pkginfo.txt 201 | *.appx 202 | 203 | # Visual Studio cache files 204 | # files ending in .cache can be ignored 205 | *.[Cc]ache 206 | # but keep track of directories ending in .cache 207 | !*.[Cc]ache/ 208 | 209 | # Others 210 | ClientBin/ 211 | ~$* 212 | *~ 213 | *.dbmdl 214 | *.dbproj.schemaview 215 | *.jfm 216 | *.pfx 217 | *.publishsettings 218 | orleans.codegen.cs 219 | 220 | # Including strong name files can present a security risk 221 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 222 | #*.snk 223 | 224 | # Since there are multiple workflows, uncomment next line to ignore bower_components 225 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 226 | #bower_components/ 227 | 228 | # RIA/Silverlight projects 229 | Generated_Code/ 230 | 231 | # Backup & report files from converting an old project file 232 | # to a newer Visual Studio version. Backup files are not needed, 233 | # because we have git ;-) 234 | _UpgradeReport_Files/ 235 | Backup*/ 236 | UpgradeLog*.XML 237 | UpgradeLog*.htm 238 | ServiceFabricBackup/ 239 | *.rptproj.bak 240 | 241 | # SQL Server files 242 | *.mdf 243 | *.ldf 244 | *.ndf 245 | 246 | # Business Intelligence projects 247 | *.rdl.data 248 | *.bim.layout 249 | *.bim_*.settings 250 | *.rptproj.rsuser 251 | 252 | # Microsoft Fakes 253 | FakesAssemblies/ 254 | 255 | # GhostDoc plugin setting file 256 | *.GhostDoc.xml 257 | 258 | # Node.js Tools for Visual Studio 259 | .ntvs_analysis.dat 260 | node_modules/ 261 | 262 | # Visual Studio 6 build log 263 | *.plg 264 | 265 | # Visual Studio 6 workspace options file 266 | *.opt 267 | 268 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 269 | *.vbw 270 | 271 | # Visual Studio LightSwitch build output 272 | **/*.HTMLClient/GeneratedArtifacts 273 | **/*.DesktopClient/GeneratedArtifacts 274 | **/*.DesktopClient/ModelManifest.xml 275 | **/*.Server/GeneratedArtifacts 276 | **/*.Server/ModelManifest.xml 277 | _Pvt_Extensions 278 | 279 | # Paket dependency manager 280 | .paket/paket.exe 281 | paket-files/ 282 | 283 | # FAKE - F# Make 284 | .fake/ 285 | 286 | # JetBrains Rider 287 | .idea/ 288 | *.sln.iml 289 | 290 | # CodeRush 291 | .cr/ 292 | 293 | # Python Tools for Visual Studio (PTVS) 294 | __pycache__/ 295 | *.pyc 296 | 297 | # Cake - Uncomment if you are using it 298 | # tools/** 299 | # !tools/packages.config 300 | 301 | # Tabs Studio 302 | *.tss 303 | 304 | # Telerik's JustMock configuration file 305 | *.jmconfig 306 | 307 | # BizTalk build output 308 | *.btp.cs 309 | *.btm.cs 310 | *.odx.cs 311 | *.xsd.cs 312 | 313 | # OpenCover UI analysis results 314 | OpenCover/ 315 | 316 | # Azure Stream Analytics local run output 317 | ASALocalRun/ 318 | 319 | # MSBuild Binary and Structured Log 320 | *.binlog 321 | 322 | # NVidia Nsight GPU debugger configuration file 323 | *.nvuser 324 | 325 | # MFractors (Xamarin productivity tool) working folder 326 | .mfractor/ 327 | 328 | # The below is for node project 329 | # Logs 330 | logs 331 | *.log 332 | npm-debug.log* 333 | yarn-debug.log* 334 | yarn-error.log* 335 | 336 | # Runtime data 337 | pids 338 | *.pid 339 | *.seed 340 | *.pid.lock 341 | 342 | # Directory for instrumented libs generated by jscoverage/JSCover 343 | lib-cov 344 | 345 | # Coverage directory used by tools like istanbul 346 | coverage 347 | 348 | # nyc test coverage 349 | .nyc_output 350 | 351 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 352 | .grunt 353 | 354 | # Bower dependency directory (https://bower.io/) 355 | bower_components 356 | 357 | # node-waf configuration 358 | .lock-wscript 359 | 360 | # Compiled binary addons (https://nodejs.org/api/addons.html) 361 | build/Release 362 | 363 | # Dependency directories 364 | node_modules/ 365 | jspm_packages/ 366 | 367 | # TypeScript v1 declaration files 368 | typings/ 369 | 370 | # Optional npm cache directory 371 | .npm 372 | 373 | # Optional eslint cache 374 | .eslintcache 375 | 376 | # Optional REPL history 377 | .node_repl_history 378 | 379 | # Output of 'npm pack' 380 | *.tgz 381 | 382 | # Yarn Integrity file 383 | .yarn-integrity 384 | 385 | # dotenv environment variables file 386 | .env 387 | 388 | # next.js build output 389 | .next 390 | 391 | # Local sample bots 392 | MyBots/* 393 | 394 | #tmp.zip 395 | *.zip 396 | 397 | #DS_Store 398 | *.DS_Store 399 | 400 | # VsCode 401 | Composer/.vscode/ 402 | 403 | # Docker App Data 404 | .appdata 405 | docker-compose.override.yml 406 | 407 | *.tsbuildinfo 408 | 409 | # Yarn Berry (v2+) 410 | **/.pnp.* 411 | **/.yarn/* 412 | !**/.yarn/patches 413 | !**/.yarn/plugins 414 | !**/.yarn/releases 415 | !**/.yarn/sdks 416 | !**/.yarn/versions 417 | 418 | appsettings.json -------------------------------------------------------------------------------- /GPTVirtualAssistant/Controllers/BotController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Mvc; 6 | using Microsoft.Bot.Builder; 7 | using Microsoft.Bot.Builder.Dialogs.Adaptive.Runtime.Settings; 8 | using Microsoft.Bot.Builder.Integration.AspNet.Core; 9 | using Microsoft.Extensions.Configuration; 10 | using Microsoft.Extensions.Logging; 11 | 12 | namespace GPTVirtualAssistant.Controllers 13 | { 14 | // This ASP Controller is created to handle a request. Dependency Injection will provide the Adapter and IBot 15 | // implementation at runtime. Multiple different IBot implementations running at different endpoints can be 16 | // achieved by specifying a more specific type for the bot constructor argument. 17 | [ApiController] 18 | public class BotController : ControllerBase 19 | { 20 | private readonly Dictionary _adapters = new Dictionary(); 21 | private readonly IBot _bot; 22 | private readonly ILogger _logger; 23 | 24 | public BotController( 25 | IConfiguration configuration, 26 | IEnumerable adapters, 27 | IBot bot, 28 | ILogger logger) 29 | { 30 | _bot = bot ?? throw new ArgumentNullException(nameof(bot)); 31 | _logger = logger; 32 | 33 | var adapterSettings = configuration.GetSection(AdapterSettings.AdapterSettingsKey).Get>() ?? new List(); 34 | adapterSettings.Add(AdapterSettings.CoreBotAdapterSettings); 35 | 36 | foreach (var adapter in adapters ?? throw new ArgumentNullException(nameof(adapters))) 37 | { 38 | var settings = adapterSettings.FirstOrDefault(s => s.Enabled && s.Type == adapter.GetType().FullName); 39 | 40 | if (settings != null) 41 | { 42 | _adapters.Add(settings.Route, adapter); 43 | } 44 | } 45 | } 46 | 47 | [HttpPost] 48 | [HttpGet] 49 | [Route("api/{route}")] 50 | public async Task PostAsync(string route) 51 | { 52 | if (string.IsNullOrEmpty(route)) 53 | { 54 | _logger.LogError($"PostAsync: No route provided."); 55 | throw new ArgumentNullException(nameof(route)); 56 | } 57 | 58 | if (_adapters.TryGetValue(route, out IBotFrameworkHttpAdapter adapter)) 59 | { 60 | if (_logger.IsEnabled(LogLevel.Debug)) 61 | { 62 | _logger.LogInformation($"PostAsync: routed '{route}' to {adapter.GetType().Name}"); 63 | } 64 | 65 | // Delegate the processing of the HTTP POST to the appropriate adapter. 66 | // The adapter will invoke the bot. 67 | await adapter.ProcessAsync(Request, Response, _bot).ConfigureAwait(false); 68 | } 69 | else 70 | { 71 | _logger.LogError($"PostAsync: No adapter registered and enabled for route {route}."); 72 | throw new KeyNotFoundException($"No adapter registered and enabled for route {route}."); 73 | } 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /GPTVirtualAssistant/Controllers/SkillController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | using Microsoft.AspNetCore.Mvc; 4 | using Microsoft.Bot.Builder; 5 | using Microsoft.Bot.Builder.Integration.AspNet.Core; 6 | using Microsoft.Bot.Schema; 7 | using Microsoft.Extensions.Logging; 8 | 9 | namespace GPTVirtualAssistant.Controllers 10 | { 11 | /// 12 | /// A controller that handles skill replies to the bot. 13 | /// 14 | [ApiController] 15 | [Route("api/skills")] 16 | public class SkillController : ChannelServiceController 17 | { 18 | private readonly ILogger _logger; 19 | 20 | public SkillController(ChannelServiceHandlerBase handler, ILogger logger) 21 | : base(handler) 22 | { 23 | _logger = logger; 24 | } 25 | 26 | public override Task ReplyToActivityAsync(string conversationId, string activityId, Activity activity) 27 | { 28 | try 29 | { 30 | if (_logger.IsEnabled(LogLevel.Debug)) 31 | { 32 | _logger.LogDebug($"ReplyToActivityAsync: conversationId={conversationId}, activityId={activityId}"); 33 | } 34 | 35 | return base.ReplyToActivityAsync(conversationId, activityId, activity); 36 | } 37 | catch (Exception ex) 38 | { 39 | _logger.LogError(ex, $"ReplyToActivityAsync: {ex}"); 40 | throw; 41 | } 42 | } 43 | 44 | public override Task SendToConversationAsync(string conversationId, Activity activity) 45 | { 46 | try 47 | { 48 | if (_logger.IsEnabled(LogLevel.Debug)) 49 | { 50 | _logger.LogDebug($"SendToConversationAsync: conversationId={conversationId}"); 51 | } 52 | 53 | return base.SendToConversationAsync(conversationId, activity); 54 | } 55 | catch (Exception ex) 56 | { 57 | _logger.LogError(ex, $"SendToConversationAsync: {ex}"); 58 | throw; 59 | } 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /GPTVirtualAssistant/GPTVirtualAssistant.botproj: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://raw.githubusercontent.com/microsoft/BotFramework-Composer/main/Composer/packages/server/schemas/botproject.schema", 3 | "name": "GPTVirtualAssistant", 4 | "skills": {} 5 | } -------------------------------------------------------------------------------- /GPTVirtualAssistant/GPTVirtualAssistant.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netcoreapp3.1 5 | OutOfProcess 6 | 88592b1b-3b29-4a1c-99d5-cf2dc4f842bd 7 | 8 | 9 | 10 | PreserveNewest 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /GPTVirtualAssistant/GPTVirtualAssistant.dialog: -------------------------------------------------------------------------------- 1 | { 2 | "$kind": "Microsoft.AdaptiveDialog", 3 | "$designer": { 4 | "name": "GPTVirtualAssistant", 5 | "description": "", 6 | "id": "A79tBe" 7 | }, 8 | "autoEndDialog": true, 9 | "defaultResultProperty": "dialog.result", 10 | "triggers": [ 11 | { 12 | "$kind": "Microsoft.OnMessageActivity", 13 | "$designer": { 14 | "id": "qHBDzl", 15 | "name": "Message received (Message received activity)" 16 | }, 17 | "actions": [ 18 | { 19 | "$kind": "Microsoft.SetProperty", 20 | "$designer": { 21 | "id": "ApoolC" 22 | }, 23 | "property": "conversation.context.messages", 24 | "value": "=coalesce(conversation.context.messages, [])" 25 | }, 26 | { 27 | "$kind": "Microsoft.IfCondition", 28 | "$designer": { 29 | "id": "iSuaOv" 30 | }, 31 | "condition": "=count(conversation.context.messages) > settings.openai.max_messages", 32 | "actions": [ 33 | { 34 | "$kind": "Microsoft.SetProperty", 35 | "$designer": { 36 | "id": "5nfF5B" 37 | }, 38 | "property": "conversation.context.messages", 39 | "value": "=subArray(conversation.context.messages, 2, count(conversation.context.messages))" 40 | } 41 | ] 42 | }, 43 | { 44 | "$kind": "Microsoft.SwitchCondition", 45 | "$designer": { 46 | "id": "PXgnBj" 47 | }, 48 | "cases": [ 49 | { 50 | "value": "RESET_CONVERSATION", 51 | "actions": [ 52 | { 53 | "$kind": "Microsoft.SetProperty", 54 | "$designer": { 55 | "id": "XVuI3J" 56 | }, 57 | "property": "conversation.context.messages", 58 | "value": "=[]" 59 | }, 60 | { 61 | "$kind": "Microsoft.SendActivity", 62 | "$designer": { 63 | "id": "4mZVbC" 64 | }, 65 | "activity": "${SendActivity_4mZVbC()}" 66 | }, 67 | { 68 | "$kind": "Microsoft.EndDialog", 69 | "$designer": { 70 | "id": "aixin3" 71 | } 72 | } 73 | ] 74 | }, 75 | { 76 | "value": "SET_PROMPT", 77 | "actions": [ 78 | { 79 | "$kind": "Microsoft.SendActivity", 80 | "$designer": { 81 | "id": "N4sj6t" 82 | }, 83 | "activity": "${SendActivity_N4sj6t()}" 84 | }, 85 | { 86 | "$kind": "Microsoft.SetProperty", 87 | "$designer": { 88 | "id": "KWhTOA" 89 | }, 90 | "property": "conversation.context.gpt_prompt", 91 | "value": "='<|im_start|>system\\n' + replace(turn.activity.text, 'SET_PROMPT ', '') + '\\n\\n\\n<|im_end|>'" 92 | }, 93 | { 94 | "$kind": "Microsoft.SetProperty", 95 | "$designer": { 96 | "id": "G2x7bO" 97 | }, 98 | "property": "conversation.context.messages", 99 | "value": "=[]" 100 | } 101 | ] 102 | } 103 | ], 104 | "default": [ 105 | { 106 | "$kind": "Microsoft.EditArray", 107 | "$designer": { 108 | "id": "0de1xo" 109 | }, 110 | "changeType": "push", 111 | "itemsProperty": "conversation.context.messages", 112 | "value": "='<|im_start|>user\\n' + turn.activity.text + '\\n\\n\\n<|im_end|>'" 113 | }, 114 | { 115 | "$kind": "Microsoft.HttpRequest", 116 | "$designer": { 117 | "id": "xGDgaw" 118 | }, 119 | "resultProperty": "conversation.context.gpt_response", 120 | "method": "POST", 121 | "body": "={ \"prompt\": conversation.context.gpt_prompt + '\\n' + join(conversation.context.messages, '') + '\\n<|im_start|>assistant ', \"max_tokens\": 800, \"stop\": [\"<|im_end|>\"], \"frequency_penalty\": 0, \"presence_penalty\": 0, \"top_p\": 0.95, \"temperature\": 0.7 }", 122 | "contentType": "application/json", 123 | "responseType": "json", 124 | "headers": { 125 | "api-key": "=settings.openai.apikey" 126 | }, 127 | "url": "=\"https://\"+ settings.openai.account + \".openai.azure.com/openai/deployments/\"+ settings.openai.deployment + \"/completions?api-version=2022-12-01\"" 128 | }, 129 | { 130 | "$kind": "Microsoft.EditArray", 131 | "$designer": { 132 | "id": "ZQ8D95" 133 | }, 134 | "changeType": "push", 135 | "itemsProperty": "conversation.context.messages", 136 | "value": "='<|im_start|>assistant\\n' + conversation.context.gpt_response.content.choices[0].text + '\\n\\n\\n<|im_end|>\\n'" 137 | }, 138 | { 139 | "$kind": "Microsoft.SendActivity", 140 | "$designer": { 141 | "id": "HUzaKb" 142 | }, 143 | "activity": "${SendActivity_HUzaKb()}" 144 | } 145 | ], 146 | "condition": "split(turn.activity.text, ' ')[0]" 147 | } 148 | ] 149 | } 150 | ], 151 | "generator": "GPTVirtualAssistant.lg", 152 | "id": "GPTVirtualAssistant", 153 | "recognizer": "GPTVirtualAssistant.lu.qna" 154 | } 155 | -------------------------------------------------------------------------------- /GPTVirtualAssistant/Nuget.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /GPTVirtualAssistant/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.AspNetCore.Hosting; 3 | using Microsoft.Bot.Builder.Dialogs.Adaptive.Runtime.Extensions; 4 | using Microsoft.Extensions.Configuration; 5 | using Microsoft.Extensions.Hosting; 6 | 7 | namespace GPTVirtualAssistant 8 | { 9 | public class Program 10 | { 11 | public static void Main(string[] args) 12 | { 13 | CreateHostBuilder(args).Build().Run(); 14 | } 15 | 16 | public static IHostBuilder CreateHostBuilder(string[] args) => 17 | Host.CreateDefaultBuilder(args) 18 | .ConfigureAppConfiguration((hostingContext, builder) => 19 | { 20 | var applicationRoot = AppDomain.CurrentDomain.BaseDirectory; 21 | var environmentName = hostingContext.HostingEnvironment.EnvironmentName; 22 | var settingsDirectory = "settings"; 23 | 24 | builder.AddBotRuntimeConfiguration(applicationRoot, settingsDirectory, environmentName); 25 | 26 | builder.AddCommandLine(args); 27 | }) 28 | .ConfigureWebHostDefaults(webBuilder => 29 | { 30 | webBuilder.UseStartup(); 31 | }); 32 | } 33 | } -------------------------------------------------------------------------------- /GPTVirtualAssistant/README.md: -------------------------------------------------------------------------------- 1 | # Welcome to your new bot 2 | 3 | This bot project was created using the Empty Bot template, and contains a minimal set of files necessary to have a working bot. 4 | 5 | ## Next steps 6 | 7 | ### Start building your bot 8 | 9 | Composer can help guide you through getting started building your bot. From your bot settings page (the wrench icon on the left navigation rail), click on the rocket-ship icon on the top right for some quick navigation links. 10 | 11 | Another great resource if you're just getting started is the **[guided tutorial](https://docs.microsoft.com/en-us/composer/tutorial/tutorial-introduction)** in our documentation. 12 | 13 | ### Connect with your users 14 | 15 | Your bot comes pre-configured to connect to our Web Chat and DirectLine channels, but there are many more places you can connect your bot to - including Microsoft Teams, Telephony, DirectLine Speech, Slack, Facebook, Outlook and more. Check out all of the places you can connect to on the bot settings page. 16 | 17 | ### Publish your bot to Azure from Composer 18 | 19 | Composer can help you provision the Azure resources necessary for your bot, and publish your bot to them. To get started, create a publishing profile from your bot settings page in Composer (the wrench icon on the left navigation rail). Make sure you only provision the optional Azure resources you need! 20 | 21 | ### Extend your bot with packages 22 | 23 | From Package Manager in Composer you can find useful packages to help add additional pre-built functionality you can add to your bot - everything from simple dialogs & custom actions for working with specific scenarios to custom adapters for connecting your bot to users on clients like Facebook or Slack. 24 | 25 | ### Extend your bot with code 26 | 27 | You can also extend your bot with code - simply open up the folder that was generated for you in the location you chose during the creation process with your favorite IDE (like Visual Studio). You can do things like create custom actions that can be used during dialog flows, create custom middleware to pre-process (or post-process) messages, and more. See [our documentation](https://aka.ms/bf-extend-with-code) for more information. 28 | -------------------------------------------------------------------------------- /GPTVirtualAssistant/Startup.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Builder; 2 | using Microsoft.AspNetCore.Hosting; 3 | using Microsoft.AspNetCore.StaticFiles; 4 | using Microsoft.Bot.Builder.Dialogs.Adaptive.Runtime.Extensions; 5 | using Microsoft.Bot.Builder.Integration.AspNet.Core; 6 | using Microsoft.Extensions.Configuration; 7 | using Microsoft.Extensions.DependencyInjection; 8 | using Microsoft.Extensions.Hosting; 9 | 10 | namespace GPTVirtualAssistant 11 | { 12 | public class Startup 13 | { 14 | public Startup(IConfiguration configuration) 15 | { 16 | Configuration = configuration; 17 | } 18 | 19 | public IConfiguration Configuration { get; } 20 | 21 | // This method gets called by the runtime. Use this method to add services to the container. 22 | public void ConfigureServices(IServiceCollection services) 23 | { 24 | services.AddControllers().AddNewtonsoftJson(options => { 25 | options.SerializerSettings.MaxDepth = HttpHelper.BotMessageSerializerSettings.MaxDepth; 26 | }); 27 | services.AddBotRuntime(Configuration); 28 | } 29 | 30 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 31 | public void Configure(IApplicationBuilder app, IWebHostEnvironment env) 32 | { 33 | if (env.IsDevelopment()) 34 | { 35 | app.UseDeveloperExceptionPage(); 36 | } 37 | 38 | app.UseDefaultFiles(); 39 | 40 | // Set up custom content types - associating file extension to MIME type. 41 | var provider = new FileExtensionContentTypeProvider(); 42 | provider.Mappings[".lu"] = "application/vnd.microsoft.lu"; 43 | provider.Mappings[".qna"] = "application/vnd.microsoft.qna"; 44 | 45 | // Expose static files in manifests folder for skill scenarios. 46 | app.UseStaticFiles(new StaticFileOptions 47 | { 48 | ContentTypeProvider = provider 49 | }); 50 | app.UseWebSockets(); 51 | app.UseRouting(); 52 | app.UseAuthorization(); 53 | app.UseEndpoints(endpoints => 54 | { 55 | endpoints.MapControllers(); 56 | }); 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /GPTVirtualAssistant/dialogs/emptyBot/knowledge-base/en-us/emptyBot.en-us.qna: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/aoai-virtual-assistant/c45bc408d313edbde4c3bf80aa8a0e771a1c7b92/GPTVirtualAssistant/dialogs/emptyBot/knowledge-base/en-us/emptyBot.en-us.qna -------------------------------------------------------------------------------- /GPTVirtualAssistant/knowledge-base/en-us/GPTVirtualAssistant.en-us.qna: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/aoai-virtual-assistant/c45bc408d313edbde4c3bf80aa8a0e771a1c7b92/GPTVirtualAssistant/knowledge-base/en-us/GPTVirtualAssistant.en-us.qna -------------------------------------------------------------------------------- /GPTVirtualAssistant/language-generation/en-us/GPTVirtualAssistant.en-us.lg: -------------------------------------------------------------------------------- 1 | [import](common.lg) 2 | 3 | # SendActivity_Greeting() 4 | [Activity 5 | Text = ${SendActivity_Greeting_text()} 6 | ] 7 | 8 | # SendActivity_Greeting_text() 9 | - Welcome to your bot. 10 | 11 | # SendActivity_DidNotUnderstand() 12 | [Activity 13 | Text = ${SendActivity_DidNotUnderstand_text()} 14 | ] 15 | 16 | # SendActivity_DidNotUnderstand_text() 17 | - Sorry, I didn't get that. 18 | # SendActivity_4mZVbC() 19 | [Activity 20 | Text = ${SendActivity_4mZVbC_text()} 21 | ] 22 | 23 | # SendActivity_N4sj6t() 24 | [Activity 25 | Text = ${SendActivity_N4sj6t_text()} 26 | ] 27 | 28 | # SendActivity_HUzaKb() 29 | [Activity 30 | Text = ${SendActivity_HUzaKb_text()} 31 | ] 32 | 33 | # SendActivity_HUzaKb_text() 34 | - ${conversation.context.gpt_response.content.choices[0].text} 35 | # SendActivity_4mZVbC_text() 36 | - Resetting conversation. 37 | # SendActivity_N4sj6t_text() 38 | - Setting new prompt. -------------------------------------------------------------------------------- /GPTVirtualAssistant/language-generation/en-us/common.en-us.lg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/aoai-virtual-assistant/c45bc408d313edbde4c3bf80aa8a0e771a1c7b92/GPTVirtualAssistant/language-generation/en-us/common.en-us.lg -------------------------------------------------------------------------------- /GPTVirtualAssistant/language-understanding/en-us/GPTVirtualAssistant.en-us.lu: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/aoai-virtual-assistant/c45bc408d313edbde4c3bf80aa8a0e771a1c7b92/GPTVirtualAssistant/language-understanding/en-us/GPTVirtualAssistant.en-us.lu -------------------------------------------------------------------------------- /GPTVirtualAssistant/media/create-azure-resource-command-line.png: -------------------------------------------------------------------------------- 1 | �PNG 2 |  3 | IHDRZ���sRGB���gAMA�� �a pHYs���+�IDATx^�=�$י����V0#��r�5�`A FK ɉ`̠�h�(�Md4�&R�ש@��-%���c6����X�_��M���V8� 2h�t׾��U��{��TWu߿�����N����}���ϝ;WdB!����B!�+#�B!��9 4 | E�����$�>|�r��W�C!�3�B�?������+�m�'?�|�}�/"~̛ �JPes�����!�8 L�20@�L^�d;ײl�N�}���}f���ӀE�=�C�������?� 5 | � ��wi��6����2�o�����w('=�Bqp�<\��,;���Ӡ��{P>,��?ğ��1�(��l�ry���׋�-|�_��-�c�X<�����_��/�\'���?�,�׮��p ��.�{���~V�[��1���� K{W�)�k�z~�ˏK�yܖ�]�o�_{>�lH��z�0V� ����C�G!Nӝ����v�������K4���p(�c4��������q �y4�oC0�A��>>' ��wb�����~ 6 | ~�.�w�^��߻_���yV���]\˿�=�YR�=H����_B�0yןɳ9���G�}[O�#~[ߖ�� OC�� �R�$�<�^�y�}��\w>�_@�2�.��{H�{W ����U�{ e\ �3� �������/a�m��3��t��m)������a 7 | �=���_=\>M�G!� 8 | ��������a��B/���z�Z�A�`�g9��/���C`��0^�H@�'�eD�c~�{�����n�Ȼp�arh|��4�Z*�����)���[��G;����r�b���;6�������w� ����~<�<@^�n�ߠ�|b�G!����_�8����� �7^ 9 | ��7�e��P��E�;o����Z�h����� P��'O������<µ���<�S*���P lK��#����8�+˶�̸0~�B�j�?`��� 10 | 3��:��pB��R(8tLaR�ᓺ8�=n��>[���m� :�C��zЯ�/��(��A� +�)�[8ߊ��N�-6��'�Z6/��_���ro�F�����X5�*��(�����k�T�Q~uX�܄B,p 11 | ��G�\.6[$X��3����̓�M��ӗ��l�3#�;�V��^t��^'��0_L`����{�����)�TӔE����H"t��Q�y^���������F<����������ӫ�7�߀?���B��m�,�8uB�M����p�s%��^*�j�p�sۅ@jDNh�w����5ƞ��s�c�C~��~��;W��<� /ȏz�A�ڠ�V��Wa�Cy�aՖ����" �Z7q��[���et�і�賤͝ 12 | V����~[�Yc� ��;���� ��|[�I! �v�� uB�M �`-���4P5g�ﶭ���RH���Yw��B���������0��9���~!��h���ؐ�X� 13 | ��� !�8=H�B!�`4�!�B��H�B!�`4�q�Xe��Y��YҰ��8���4�"����_���1�BQ? �n r���{�>��ڰ�v��q���I��W�����Y �.�M��Bі�U��-e�)B��`U�bB����O��.*���45�rR�I��ހ���_�\c0�E����a69�X�.��Eٹ�N�2a��Ab�保$Z->�}B�����^X�S�R9��1EϐJ�m?����z��Q�z/��������o#ܺ9���H��=tˮ-NS�m�]�}`�Fa����Ʈ� �o����.���8,����r7��/���6B1 ޛ���\�O����(Xy��� 3���F�!G�OݿFh>{�S4��e�᷅� ���w�^������?��)n�qfЌN-���+-�w�4:�H#MS�lBЖ ����8}}��.�!����8Vh�%�d} S���2���U>�Ubrsw��B�����?6mQV!��j��™ˆ����K�$�a��[�$�熞�즿�"� \g�:�7�B��]P0TƸh]�E}�#�7���*�����$˽����h���2�4���\>]�R�+Lw��{PvR�� 14 | !��*�,�4׌f�r4Ѓ�����z�N��*1N��Cꌔ \!�%E� �w��x�K���X����>}��Z�,�P�����t����S(�虻���t� !��Ǫ�J�p�+��orO�=v��>[������C���`_� �tF�!�.�;��U��������#)M���p=���Q��lrO,�ڪ=F��6w���O��י�s�[!NI�1�S(�<��r�C��9�p��������%!g��R�؊�P|�0#B>��V8���� :�i�9ª�H"t�����O��?�^!�H�n�~R�a�qg�� ���A�;�}�_�+X)�}���k���՛=(�k�}��� �7|�6�B%��+CB��W�;�]䆭�n��J?ܥQ�!0���Y�N����۠�uhe���[-܀0l���� ��=�a�YT~>ɲ���\z�׻��=P�8j�[��6��<����r7���o=o��X��v���vy!��#=��b���h��BqZX� 15 | !�B�� 16 | !�B FSB!��F(�B1)B!�̙P(��B�!��c��gE�I��4�W6+��YS!� le���d;��&��;us���B�9�.; �GL�Q*�T�{�3��tp��iVd�,�NK H�����-g7�oP�@8���ZhC�H��s+�cO�����������B!j��_и���J�@H�/ �Ɓ�������؂N�Pg��A�(�v��3z_7N���6)/!�p����[Y����'4����֡�n�4���Y{=DB��H�ߦ�+�B!S)Z�0(�)����U�ʧh��o�l��7����t3nh�l���l�9��q��v�B}�ş�7�T��_/��.�bJ@����^�m4.��u��ɪ����{%��ۅB�� 17 | 7~9s����gw���<ۺ��9�y��w���%!�����`l�F(�˽4� 18 | p 19 | ��e�T�2X�9������A ���^��A���(����m���&��y�7�u��ҟ#-�;xϦ�t�(Z,��� !�I`�QB��I�U��m�AP8�R[��ƨ�0�}�k��,��!?��Q�IͽkD�6Gm�HC�u�� ˊ�p�M5�Tw���������?�V�m�O�+S�o���!q7�8�����Bq�q�Lq�Fn��o�*+�8��eXu�R!�jT;!���ϱ��Fᬢ�B�S�F(:� ����8����B�� 20 | !�B FSB!�� 21 | !�B �ȧ<������\�߻��ַ}�A��E;c�OJ�B�~�P�@����=M�c�)�<^��p{��ߣ��+��G{:���q�?C9��O!R��Ǹ��r��j��\o�q4�#�≇� 8R���?���*���h�B�㈛�p=$r�I�~�V4 �2��X8M'"� i������~lˢ�~RcC�������p�c5]R;�3�p�F���gx��J`~��V�9 �~β�Jgx&YʿZަЫ|���5��O,����k�f?ȳ�'�n�g�Z<�8����'�'�����^q�Ȋ� P���� �߽k 22 | �T\@#y��I�[�D��G��R`�+����pp���yV�����$ �﹅?Fq�?����]c��C#����}�" ������7��_��w��am�S`L���g�l!q�Qy�֓A~ ~[ߖ�� OC� �R�$@7�Q� .߇��-���w>����O�����/����v�������|�B�M�C� ������������~�p94�Y>-���[@�� ]���V*���([W�_-�ϐ��O���3V~ ��y�\� ���R�s�ox��45���Qխ��'�'�j �iɓ���!�R �=\J���t�3�����#�z����B�u�o�����V 2� ��[ˏ��M�'���X������`X4|u�K�ሁ� Jb�[���6��DW�����P������ p��� ��q�O���s�U��̛٧�O��(��Y!��'���!���J�p�4�M��h�B�ր��T 23 | �'4�5�S�k ��C�.M`Q8%PpN��u���A+��zrJA_�Y<�0����}�Rɬ�ﭲҤ 24 | t�X>C��G{C!�C �9������a�me��B�D�Ppj��!��,>4!G��ԛ��:�܂��<5GA�I���q�GA�� ���p}B+pv��s�uS�\�a�p$f�h��-��c=峒�]JJd�_�� 25 | �4����P�֐?BqRq 26 | ���\.V[�!�i�i}����8����� 4��mN��?�`�-rK 27 | ��5!=N���|��M��v��>��RHZ�-"l��84B��Mń��%�/峊�9� ��Vj���0OC���ב����#] �c`�c=�Q��C݅"�mt{�Z�=�:~�cA��}�!��6{�~�^����yS�����a����_� ������� ΫsK�6���߅�߭�_�$>�C��{�^H�5��j�Ka�ۜ>�sjF�Ļ�P�i�]-�]�CR�_��H��%Տ��^���u�֋>O'��O*C��h�Bq��q�5�F�4���8!�n�q��T���6�B�f�5b p����kl_=�U(���S!�!4B�fb���"�f�=r�͠)?!�R(�B1My!�b0R(�B1g��?���������\��b���n?�F�8����s���G�e�q�tM�g�-�'���}����{���t򌞭G�����Ib��3��5�'��8��%N$�F(��Z�c=mq�@��[��)��G�xx���5�o��'����^9�徉��,��P���; ��\���@q�p[ dv��}�w���0����Ë����1qG>�*7� ��u���l��,�v�����˺�O�R!�~�_����i����>�n���s2�]�T�^�m ̮A���ĶU�-~��S �c�#�=��X\��­��&���X�$���F���gx�����;|�¢��N��y����Y�W�S��D��'�X�io�-~C��py9�'�)�����'d)�!>a�Wq�_W�G�K����޿ �M��p鈼�d�|Hb��_�������i]*����B[�m4�����lp�1�˧!��;�������P�Q�B�~��K4�s]��@����M|��?�y�L��]_���*��&�y �<�J}��d��QџAEC#w��2[/������\��Q5X�x�]�?��j�|�t�q!�����h ~[�^�]<���7Njp�ߓ�����o���?���}�{��@a3E;�q�>�~n9��ߕ��g�7�e���(]-~�=���H��G����|ۢ���x�߆?w��k��rn+���lϻx�]��ů� 28 | ��ý��*��V~Ą!Q���_0�����`u����D��H��:\�MP����GP���?4�m�������i��oR/�D��ѕ���3�W�ݻ���d��|���]����q�6r���-�V�^L�8|��3����R���iM?�6yx�.��G���se��ɹ�m�1p 4��/y̶D8%��h� 4~Պ��t 29 | ���;3����.�^�.hhl7�ow�Û�#<\Ke�BkhJ��j2�I�k�j����O' �'���*?��e-�G�=����B���7?�8'�����~�/�!�oɿ��o(���{�h�3t�R&�zr�i!5�(���R1�:W�j�����@�����8>,/��tre�B��LSI�E�4P�@GY+�q�qƳ���4@��e'�Bk�ȳ>£�?PH̔v7��!U�.�boz��#��kCh��T�����^@9L�%�_ոzk��H�_k����53$������ ��O����a��<��18��9���OJ��P���+'( 30 | V�9ڿg��2#N5,{5\V�q Z����s|��M�r�f���xH�F� 31 | � ���B!�u�z�@#w/m�oM��Ւ5Mh�u-���V {2��J�D���3բ\Z#�o�7}?(�l4���:��kL_��ǿ)� ����#��a��/���Q�:���ۭ�A� �ߩ�w�v�-�f��S ��~WvA�A�>�B���.gn1PAR�/��ѧ?�0x�ߐ@�{��*4{Cӫ�7`O������0\�^�%T�`xv(�A��|�^��EMQ|/|�>͋S���[��0���]!����J���������00����>���0c#n}�WO_ 32 | Uڦ�64�7�]�������Ϻ�N��-��%)|mƵ_ � 33 | �R�� �ߩ�7�����'�K��m����;�e�m�&ZF�����_y����N�5~�˨� ga��G�8�_M��F��vWWq��TOK���Cs�-��{�.�C�\�6���G4�0����Uڭ鯕��zfa�Vg�h$�?�l-��������N�I-��2�ڥ`ϧ�/+��.�P8��������w�_���V?��O���ߟd�v���)�-:5f�I{���兵s�<��+�.\g�wjx�+�u��_b�y_�.sc�v� u��H��Ye +�:XW8��-mk����֙&q��)�B�R:��c�SM~ 34 | �����S�k�_��EQ��P� ���vP qR�GuVڡ&N�z�"�]�PX}8�p�Ґ�(�t�F���(!N;��g�R�x8R�B!���31�!�B��"�B!���B!�B��H�B!�`�P!�b0R(�B1)B!�� 35 | !�B F 36 | �B!�e� �lo���IEND�B`� -------------------------------------------------------------------------------- /GPTVirtualAssistant/media/publish-az-login.png: -------------------------------------------------------------------------------- 1 | �PNG 2 |  3 | IHDR�R��(sRGB���gAMA�� �a pHYs���+"�IDATx^���o�F��G{��}�,�IQ��y�A�^�(4v�>�)�x��:$@Z���}۵�c���ձ��C����б9�E���c��|�CrH���H���B#Ѥ�7g8C����;?<N��?��@�0���9�� �=4��qH��:�l��O&K��]ۡf�h�io���=�ߊBa��=kR�ZT��M'rK�&=�F �/��q����=�^��q(_�l���Pݠ��g���J�?θ-h�۴���.A�K��w�����}{�����p�J�(��^˼�W�]�g���T`��9E�� �P����2u�i�dt �#.�W��Y��'M��H^.�E\4�di5q�Ǒ�~M:]��.HI�银��v�ԯ�%��*?�=l�S:�q7)_yK�a���0�����*��I`����۷<�]&�GL n��s��s���Q�V}������1���lA����k:����%�~�Lz���ƟO�v�XX�S�ԠÝ5�-���N�~��פ3�_�A�iïaw�ۛJ����\^c��� ����_o�����O'��b���V�-� ��I'm���W�}L`��σK1�'y�oy�.�ٶ/T�:t�&D&�p���j�hu8���'[|�� 4 | ���ahLJ���6��� �)r�}�6����U��?�K���+����c���$|y��~g��g}u(I���qn�����g^L��7ȗ=�=3M%j�Ѿx7��#j+��$f�=�Z�?å./�ƢA�v�� 6 | �@qc׬S}a�o�Hw|!E�/�$�W|B�R�cye�z�[%j<�|2 �`$��,�Ē3��[n�ujY�?u��lR>�����CN�l����W���\!NU~4��$�t�g�7Kj{���]���ˤ����Dަ�Q�*��+�@f�n���u�*u�O�{)&�t�g�~q��ı��_�PE����_��~�,��U�M�?X�8� 7 | ���>���׆?���b���cz-��.�t���i�������b�����}��`R�������f�jM�����޾�Z ��7ȟ=�>�?7���G,���أ� ��節���ϕ{�zꝑ��/��^�����:�cW����?����"U�m����ۻ����\�ʞǾ�D����۵NX�]r��4�~��Π��[��4�;�i Z~t�� �����%�N'ķ���Y��O[�� � 8 | <�� ��㋿����/7��Mѹs;t��^^^���ҧ_t�4���S#�����/�W�3~�7�Y�5�V�U��_C�>Q� ��"�XY����`���?�'a|\��#2�>fc���J��W�G\\�)�{��hߢ��?&�7s�����?�4O9}}��#¸#%��؝^߲q�(:YNcp �h�;�n�;��W�*���A�Y �0���V������a��t)d�.+��#�\ˏ&�R38~����>�{���M��c��ܡr���]�:䏽��N;��_�े �=,E�_\���A��Ŵ~ o�b����]���ݡ��B�"D��A��;�S$��|�k��?(��k �?��qP��Ϣk�t��~�N��'�}��w�ִovZx�]��ӽ�W�=�-�&�i.��݋�-�m�i�^�7�\�݇r9���iuB��B�+Y�y|E��_�����E�;�=/��QW9��� �ʨ|� \~t��0�QO���ϻ��4�k��3@�����O���^�]�C�x�m�ӭt��˪�K?]�̭��� bC��/N��f���,�vȿ��;�h_���A���|d� ��p�}���Z&�*m�@�����Ϣk�Lگ4�oBw�qo�"�Q�5�� 3��!��ɚ����7���{�WŃ4q�:���M'$'q��2��{�T����+f��;x����_1��s��W�ۻv�B�C��_{Y������j�o�Re�����<�#����M�=i���/M� bi��Gv�?����~�ʏ��k�+g �7-?a�D�`ۡK���K�~�?)m�����m.���G���v^x���.�,,}"�?.܆.͕"����J�H�/�G�7� _�b*q�e�?}���E�;�������Ii���P�}�k�0� ��;�_<��xcϰx��>x���p��:����gV���=�z#�z��%�o��a�� }P���U��_��!������/N�b���w��%.q���mڬwiY����Һ���V�D>/<|+���cĕ�`|�x�J�w(�����㈍\�P�j�/����u������O0mX���J����7}����8�<��wlW�o��k~W���/��,�~��=*}L�V_����?�?�mw�������d_]�IT�����g��۟�ԯ��aq�3����}����vY��]�7&�˓Q�ĝ�i&6�L�7Q���1]�Esw���kڷ8�n�l��Y�� M5���?�l��P�l��oԆ�~a'�q���8��$��aB���eK��Å� Y�m� �Wi�g-p�:0J(�>�u��߉����� +���`?4 ���!��E ��^�G�����j�+��ձ�� 11 | {����~��"������?��/�����)��N��ؽ��$�ѵ��3H��Ā�P��\9�D 㡽y��N�!ܩP0�G�C�EO���v�|n�Ҷ<ї�g��o�Hb�<'f)x�7s���"�hi���K��A��.��R�������Z_�]��$�S���o��N<��5��O��3�T)�i�)Ԗ��[u�������$������I�>;���>�>�Q��(�s�Y���@���#�i��;�9?9b�CW�Mڇ��e��0���i*y�Oȁ��L=���j���O�$V��j�o��5��K�/.�聼r�{�^�̤-���P��1�����y@.f��1�9c�s�8E�i��:ԙZ���z�}k����5������ ��9w�k����.ۿso����i��ߚ�ل=�:d����c���cZ��A��h뷦}0 _&� �p�d��拓-Z�����m�#��=�)��-��=kwoI���;T�H/M�(��:����C��嘦�σj�m�N�R#t���;�SݧtD���<�ֈoi���/"���+ܹ�����?�7/^��s��lM 14 | ���YS 15 | �&�e�� ����������>��W��+:� @o�3�?��s�һs_���$�?�I��>=���ɇ�C��nw98�����tK����n���e��G_y�K|�p����-��������l�9��7���� �]�ux�On^��~yN?�$����uq�⧤W`Eǁg��t 16 | ��� �{��Yv7��9�7����|Y�w�}W��Oޣo���;����{t���b[�X�'gDgO����L��_���� n|�W��Z�Gt�?�[�9Ǿ���N��x}f�ܙI��>��n^{E�ω���]�����;s/�]䀼����_,ػ����"E�ݽ����o�N_~���.���,}`��f��`�߼�X��o�A���K�y@��{��G����򌮽?+ޛzu������ �������j�o���_{�O?�R����� 17 | ���������=�ꟿ��ۿ�����K7���߼c>��:��䛥��%���ـ{�}�v�+�ȷ�����z<>��dϸ���_����cd4��q��]P���_]�-+w|j���yR�����;>{wξ���]��{=wIyo���{��.��ɯtv�}�Mg��kg�S��� ����s_�,7��i���r��7���+��ߗ�˾�.%���g�D.��^r@c�l���Gzyv����7��3�7�^ҏo�%ϯ�~Q������׳�A�� ���!"�v���X�)���'�����o��[k�nșQ����3�xh�x���ݥ��7�� �x��͟��o���}ϻߘ�㇐���K>%�Z���Sž�Yy����R� �� �ΧK7������x{Y9��˿���4P�g�s-W�O����f��_���=�n!���R�s������F�۽����=�L<<��S���X�9�%�:��Z��%�ex�4�%�ɀ�������=E�?� p�d����YR>p�`�܅�,�����͎�w�G��W������<��p�]��q�_�8���Y���n{����f�h�Њ�|%M�q�˿Bu#�|�3�g�v�<9ܨ�O�5I�7���T��>#� +�R���~�{����?�Y�FE���G��m�:΃�8���5�F-��ަ����Ҩ���r�}jw��%O��_�I]��ie�j�4@T��z�0�����K��A���.<���6Z�=ʤ���B��D���<)�I�q��`��i> #�y�ݜڥ�{��LR��#�tF]�/��)��{��������<�޾�����g����8٢��y��^�mk�ݪ��ϯ m��..Nhk��ޕ���,F��of�B�z9�m�2����4��MG����4�Қ��G�`0�h?��R�� 18 | Qs��۴�`��ʕxq�������?�c<ܟ�WH6� *�-�f��߻3���x���#xQ�~��a���$�J��?A�F]�����y�Swى�y����a|D����������������]���ʮJ)�q�3������C����/]���Ǘ����3P��ߟ�6� �_x�u�g�����_�~�s�ٞ�]�nD��.�ҹ.�J5���M'�ih��8^��'�?h��t�۟E� ���T\���g�������K�D�/"]*t����gi��O�=!�A�s�H\��}��_��/����O'25�oZ��򏏑��� >�'Ǡ�ס˿4�� w2� �I�6�_����|�eM�_����o����o�#Q���F�p;�;3��To�����Z��{��ֱ""����:�Z����O��֭���/,ԉ��#������<QmuIn��}?Ks��t�'2��훝5����n�Ȏ�ؿ]6����Qi:�o;���&�+7�J��6;Tk�S5������&5+�T_X����hm��-�&��"�§�]���hl��������je�v���,��_��;��<~����⯫_��-����_�~��]�05so���]߉X��\q�8��ӸHS��ͺ��>ٖ���������� �K��\����q[�U������3Ϳ8q�7j4��ʿ`�_�)b���k:����8c���,z�wL���;u����&�kt�gi�/&������O�$}��ߤ��?��#��S���˿����ʗQ���f|0���;3h�o�>fM�Y�J�M����d9�ޥv�B�9L�<�h��3]"j˵r<����G��ٺ��]�$ *��kE�� 19 | ̕{�z�%�ڢ^����v���� j��]r�)<~؍�g�4|���#jS���/���U��s�rЦ+ߚ����OT��J[ �W�_�n��y�_%|��?,*�,�~�ڷ\—w���/MxuK�8�+E7��b�[u���mת�ր�)�%�fi�l�q�@^5h��J��Ng�=qe�9�?H4�'6�&�3H��� +�*]�p�SeQ�w�=��3pq�O]?5�kL�i_M�Q��城i�?�����,�y~JSu��E� G�����Җ�<����i�� ��OQ�ץ���-uC�PG���*���O�� �_yξb�0{]�.�������tf6���+/�S�n�.���Oq��� -Nu�3�h���HdQ��D���`]\����򭋟%��� 20 | _Zi�o���%�� !|q�K۾�{�H����V�r�~�~������%Ҡ�%6}28����V��?Q�;�����`rn�Ј�6}��O[?5�7��T�]������?��N��������; � ��T�?��/��i�� �y��9Y���T�p��N���K�J�䝮��G��^^\�w�E������-w�_f'.P���:��o�%_�Ց��>�#�+g\>d#�2|�3-�Q��ʟ����A�WO���y�O��q��j��=�„t�Ҷ��*��k���۞��lx���>�ӊ�F�K�3�r� ��$Ƭ�m%������i�~#��d�?P��O'��o��׌—e�MZ�`�R��y��DƤ|E՟$�c6��@�i����K� *+�@%�,�2e/)P��Y����q���W8�{�L�]��]�g1W���gw&��{����]��x�'���W�J4�Z!�a�u��:G%yUm����s��N����;>~A��^��,��I[�i��vjG�<§�_W�t�۸�_�����/���W��`r��l���,N�۞��bmu�%� �O_�dt���_��K� ������t�CpL�/��s��\)ryl]�S�OM��ڇ���h�O'��/���K�%m�R�ߌ��+�|��W+��s�2����;�~��߼}4p�n�ޤN�)���QR�g�p;Rr_~��O<�Oz�vQ��\� 21 | ?'�Su���J8CE������J����'A^��'͊��l��c�嬈�7���p?ܴ:# ;}�)�������H�r�^��D�r���,��9��/񀄄��A�וo]���S�ۏ�E5j�������ǥ�(�o"��E�_W�LڷqH?������񐫘YI��8&�?�>��|[/~�� ]�ѥO���HS?��E���O�1?�>�x�m`��~�?�(�;�Y���뎯K?]�`�4����O'��/��gq|�Q��������*�|��WǤ�Ǎ_�,�,��Ӷ�I�Ǿ�G�I�g=�*�T\�f�Q�j5k+X��0����`�&ǩ.K��OR�&�����:�~&ġ�� �o��0]R>j|ϕ��K�#8�{���I�o��`���m�� 22 | r��t�a�!�4�>L����f�̱z���qE`�0Ý>��ܾ]����?�mb��d2��L �r�7@|���o�@4�p�@<����W�''��&�?ؓo��FY�鵨~{�N�{�}|? ���n�V�N�{�l�7��ђ�B�Js�����O�����W��j� ?��=�3�T�"՚txx(^͚�I��g����l�}zN�Q��@����k��Np7@П����n���E� ,��أ�v�j�K�p��|C̀o`�9\i�����Ԣ5����B���N�R�]R�������_�)�� �{�  �2G����b��IEND�B`� -------------------------------------------------------------------------------- /GPTVirtualAssistant/recognizers/GPTVirtualAssistant.en-us.lu.dialog: -------------------------------------------------------------------------------- 1 | { 2 | "$kind": "Microsoft.LuisRecognizer", 3 | "id": "LUIS_GPTVirtualAssistant", 4 | "applicationId": "=settings.luis.GPTVirtualAssistant_en_us_lu.appId", 5 | "version": "=settings.luis.GPTVirtualAssistant_en_us_lu.version", 6 | "endpoint": "=settings.luis.endpoint", 7 | "endpointKey": "=settings.luis.endpointKey" 8 | } 9 | -------------------------------------------------------------------------------- /GPTVirtualAssistant/recognizers/GPTVirtualAssistant.lu.dialog: -------------------------------------------------------------------------------- 1 | { 2 | "$kind": "Microsoft.MultiLanguageRecognizer", 3 | "id": "LUIS_GPTVirtualAssistant", 4 | "recognizers": {} 5 | } 6 | -------------------------------------------------------------------------------- /GPTVirtualAssistant/recognizers/GPTVirtualAssistant.lu.qna.dialog: -------------------------------------------------------------------------------- 1 | { 2 | "$kind": "Microsoft.CrossTrainedRecognizerSet", 3 | "recognizers": [] 4 | } 5 | -------------------------------------------------------------------------------- /GPTVirtualAssistant/schemas/sdk.uischema: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://schemas.botframework.com/schemas/ui/v1.0/ui.schema", 3 | "Microsoft.AdaptiveDialog": { 4 | "form": { 5 | "description": "This configures a data driven dialog via a collection of events and actions.", 6 | "helpLink": "https://aka.ms/bf-composer-docs-dialog", 7 | "hidden": [ 8 | "triggers", 9 | "generator", 10 | "selector", 11 | "schema", 12 | "dialogs" 13 | ], 14 | "label": "Adaptive dialog", 15 | "order": [ 16 | "recognizer", 17 | "*" 18 | ], 19 | "properties": { 20 | "recognizer": { 21 | "description": "To understand what the user says, your dialog needs a \"Recognizer\"; that includes example words and sentences that users may use.", 22 | "label": "Language Understanding" 23 | } 24 | } 25 | } 26 | }, 27 | "Microsoft.Ask": { 28 | "flow": { 29 | "body": { 30 | "field": "activity", 31 | "widget": "LgWidget" 32 | }, 33 | "footer": { 34 | "description": "= Default operation", 35 | "property": "=action.defaultOperation", 36 | "widget": "PropertyDescription" 37 | }, 38 | "header": { 39 | "colors": { 40 | "icon": "#5C2E91", 41 | "theme": "#EEEAF4" 42 | }, 43 | "icon": "MessageBot", 44 | "widget": "ActionHeader" 45 | }, 46 | "hideFooter": "=!action.defaultOperation", 47 | "widget": "ActionCard" 48 | }, 49 | "form": { 50 | "helpLink": "https://aka.ms/bfc-send-activity", 51 | "label": "Send a response to ask a question", 52 | "order": [ 53 | "activity", 54 | "*" 55 | ], 56 | "subtitle": "Ask Activity" 57 | }, 58 | "menu": { 59 | "label": "Ask Activity", 60 | "submenu": [ 61 | "Ask a question" 62 | ] 63 | } 64 | }, 65 | "Microsoft.AttachmentInput": { 66 | "flow": { 67 | "body": "=action.prompt", 68 | "botAsks": { 69 | "body": { 70 | "defaultContent": "", 71 | "field": "prompt", 72 | "widget": "LgWidget" 73 | }, 74 | "header": { 75 | "colors": { 76 | "icon": "#5C2E91", 77 | "theme": "#EEEAF4" 78 | }, 79 | "icon": "MessageBot", 80 | "widget": "ActionHeader" 81 | }, 82 | "widget": "ActionCard" 83 | }, 84 | "nowrap": true, 85 | "userInput": { 86 | "header": { 87 | "colors": { 88 | "icon": "#0078D4", 89 | "theme": "#E5F0FF" 90 | }, 91 | "disableSDKTitle": true, 92 | "icon": "User", 93 | "menu": "none", 94 | "widget": "ActionHeader" 95 | }, 96 | "widget": "ActionCard" 97 | }, 98 | "widget": "PromptWidget" 99 | }, 100 | "form": { 101 | "helpLink": "https://aka.ms/bfc-ask-for-user-input", 102 | "label": "Prompt for a file or an attachment", 103 | "properties": { 104 | "property": { 105 | "intellisenseScopes": [ 106 | "variable-scopes" 107 | ] 108 | } 109 | }, 110 | "subtitle": "Attachment Input" 111 | }, 112 | "menu": { 113 | "label": "File or attachment", 114 | "submenu": [ 115 | "Ask a question" 116 | ] 117 | } 118 | }, 119 | "Microsoft.BeginDialog": { 120 | "flow": { 121 | "body": { 122 | "dialog": "=action.dialog", 123 | "widget": "DialogRef" 124 | }, 125 | "footer": { 126 | "description": "= Return value", 127 | "property": "=action.resultProperty", 128 | "widget": "PropertyDescription" 129 | }, 130 | "hideFooter": "=!action.resultProperty", 131 | "widget": "ActionCard" 132 | }, 133 | "form": { 134 | "helpLink": "https://aka.ms/bfc-understanding-dialogs", 135 | "label": "Begin a new dialog", 136 | "order": [ 137 | "dialog", 138 | "options", 139 | "resultProperty", 140 | "*" 141 | ], 142 | "properties": { 143 | "resultProperty": { 144 | "intellisenseScopes": [ 145 | "variable-scopes" 146 | ] 147 | } 148 | }, 149 | "subtitle": "Begin Dialog" 150 | }, 151 | "menu": { 152 | "label": "Begin a new dialog", 153 | "submenu": [ 154 | "Dialog management" 155 | ] 156 | } 157 | }, 158 | "Microsoft.BeginSkill": { 159 | "flow": { 160 | "body": { 161 | "operation": "Host", 162 | "resource": "=coalesce(action.skillEndpoint, \"?\")", 163 | "singleline": true, 164 | "widget": "ResourceOperation" 165 | }, 166 | "footer": { 167 | "description": "= Result", 168 | "property": "=action.resultProperty", 169 | "widget": "PropertyDescription" 170 | }, 171 | "header": { 172 | "colors": { 173 | "color": "#FFFFFF", 174 | "icon": "#FFFFFF", 175 | "theme": "#004578" 176 | }, 177 | "icon": "Library", 178 | "widget": "ActionHeader" 179 | }, 180 | "hideFooter": "=!action.resultProperty", 181 | "widget": "ActionCard" 182 | }, 183 | "form": { 184 | "helpLink": "https://aka.ms/bf-composer-docs-connect-skill", 185 | "label": "Connect to a skill", 186 | "properties": { 187 | "resultProperty": { 188 | "intellisenseScopes": [ 189 | "variable-scopes" 190 | ] 191 | } 192 | }, 193 | "subtitle": "Skill Dialog" 194 | }, 195 | "menu": { 196 | "label": "Connect to a skill", 197 | "submenu": [ 198 | "Access external resources" 199 | ] 200 | } 201 | }, 202 | "Microsoft.BreakLoop": { 203 | "form": { 204 | "label": "Break out of loop", 205 | "subtitle": "Break out of loop" 206 | }, 207 | "menu": { 208 | "label": "Break out of loop", 209 | "submenu": [ 210 | "Looping" 211 | ] 212 | } 213 | }, 214 | "Microsoft.CancelAllDialogs": { 215 | "flow": { 216 | "body": { 217 | "description": "(Event)", 218 | "property": "=coalesce(action.eventName, \"?\")", 219 | "widget": "PropertyDescription" 220 | }, 221 | "widget": "ActionCard" 222 | }, 223 | "form": { 224 | "helpLink": "https://aka.ms/bfc-understanding-dialogs", 225 | "label": "Cancel all active dialogs", 226 | "subtitle": "Cancel All Dialogs" 227 | }, 228 | "menu": { 229 | "label": "Cancel all active dialogs", 230 | "submenu": [ 231 | "Dialog management" 232 | ] 233 | } 234 | }, 235 | "Microsoft.CancelDialog": { 236 | "menu": { 237 | "label": "Cancel dialog", 238 | "submenu": [ 239 | "Dialog management" 240 | ] 241 | } 242 | }, 243 | "Microsoft.ChoiceInput": { 244 | "flow": { 245 | "body": "=action.prompt", 246 | "botAsks": { 247 | "body": { 248 | "defaultContent": "", 249 | "field": "prompt", 250 | "widget": "LgWidget" 251 | }, 252 | "header": { 253 | "colors": { 254 | "icon": "#5C2E91", 255 | "theme": "#EEEAF4" 256 | }, 257 | "icon": "MessageBot", 258 | "widget": "ActionHeader" 259 | }, 260 | "widget": "ActionCard" 261 | }, 262 | "nowrap": true, 263 | "userInput": { 264 | "header": { 265 | "colors": { 266 | "icon": "#0078D4", 267 | "theme": "#E5F0FF" 268 | }, 269 | "disableSDKTitle": true, 270 | "icon": "User", 271 | "menu": "none", 272 | "widget": "ActionHeader" 273 | }, 274 | "widget": "ActionCard" 275 | }, 276 | "widget": "PromptWidget" 277 | }, 278 | "form": { 279 | "helpLink": "https://aka.ms/bfc-ask-for-user-input", 280 | "label": "Prompt with multi-choice", 281 | "properties": { 282 | "property": { 283 | "intellisenseScopes": [ 284 | "variable-scopes" 285 | ] 286 | } 287 | }, 288 | "subtitle": "Choice Input" 289 | }, 290 | "menu": { 291 | "label": "Multi-choice", 292 | "submenu": [ 293 | "Ask a question" 294 | ] 295 | } 296 | }, 297 | "Microsoft.ConfirmInput": { 298 | "flow": { 299 | "body": "=action.prompt", 300 | "botAsks": { 301 | "body": { 302 | "defaultContent": "", 303 | "field": "prompt", 304 | "widget": "LgWidget" 305 | }, 306 | "header": { 307 | "colors": { 308 | "icon": "#5C2E91", 309 | "theme": "#EEEAF4" 310 | }, 311 | "icon": "MessageBot", 312 | "widget": "ActionHeader" 313 | }, 314 | "widget": "ActionCard" 315 | }, 316 | "nowrap": true, 317 | "userInput": { 318 | "header": { 319 | "colors": { 320 | "icon": "#0078D4", 321 | "theme": "#E5F0FF" 322 | }, 323 | "disableSDKTitle": true, 324 | "icon": "User", 325 | "menu": "none", 326 | "widget": "ActionHeader" 327 | }, 328 | "widget": "ActionCard" 329 | }, 330 | "widget": "PromptWidget" 331 | }, 332 | "form": { 333 | "helpLink": "https://aka.ms/bfc-ask-for-user-input", 334 | "label": "Prompt for confirmation", 335 | "properties": { 336 | "property": { 337 | "intellisenseScopes": [ 338 | "variable-scopes" 339 | ] 340 | } 341 | }, 342 | "subtitle": "Confirm Input" 343 | }, 344 | "menu": { 345 | "label": "Confirmation", 346 | "submenu": [ 347 | "Ask a question" 348 | ] 349 | } 350 | }, 351 | "Microsoft.ContinueConversation": { 352 | "menu": { 353 | "label": "Continue conversation", 354 | "submenu": [ 355 | "Dialog management" 356 | ] 357 | } 358 | }, 359 | "Microsoft.ContinueConversationLater": { 360 | "menu": { 361 | "label": "Continue conversation later", 362 | "submenu": [ 363 | "Dialog management" 364 | ] 365 | } 366 | }, 367 | "Microsoft.ContinueLoop": { 368 | "form": { 369 | "label": "Continue loop", 370 | "subtitle": "Continue loop" 371 | }, 372 | "menu": { 373 | "label": "Continue loop", 374 | "submenu": [ 375 | "Looping" 376 | ] 377 | } 378 | }, 379 | "Microsoft.DateTimeInput": { 380 | "flow": { 381 | "body": "=action.prompt", 382 | "botAsks": { 383 | "body": { 384 | "defaultContent": "", 385 | "field": "prompt", 386 | "widget": "LgWidget" 387 | }, 388 | "header": { 389 | "colors": { 390 | "icon": "#5C2E91", 391 | "theme": "#EEEAF4" 392 | }, 393 | "icon": "MessageBot", 394 | "widget": "ActionHeader" 395 | }, 396 | "widget": "ActionCard" 397 | }, 398 | "nowrap": true, 399 | "userInput": { 400 | "header": { 401 | "colors": { 402 | "icon": "#0078D4", 403 | "theme": "#E5F0FF" 404 | }, 405 | "disableSDKTitle": true, 406 | "icon": "User", 407 | "menu": "none", 408 | "widget": "ActionHeader" 409 | }, 410 | "widget": "ActionCard" 411 | }, 412 | "widget": "PromptWidget" 413 | }, 414 | "form": { 415 | "helpLink": "https://aka.ms/bfc-ask-for-user-input", 416 | "label": "Prompt for a date or a time", 417 | "properties": { 418 | "property": { 419 | "intellisenseScopes": [ 420 | "variable-scopes" 421 | ] 422 | } 423 | }, 424 | "subtitle": "Date Time Input" 425 | }, 426 | "menu": { 427 | "label": "Date or time", 428 | "submenu": [ 429 | "Ask a question" 430 | ] 431 | } 432 | }, 433 | "Microsoft.DebugBreak": { 434 | "form": { 435 | "label": "Debug Break" 436 | }, 437 | "menu": { 438 | "label": "Debug break", 439 | "submenu": [ 440 | "Debugging options" 441 | ] 442 | } 443 | }, 444 | "Microsoft.DeleteActivity": { 445 | "menu": { 446 | "label": "Delete activity", 447 | "submenu": [ 448 | "Manage properties" 449 | ] 450 | } 451 | }, 452 | "Microsoft.DeleteProperties": { 453 | "flow": { 454 | "body": { 455 | "items": "=action.properties", 456 | "widget": "ListOverview" 457 | }, 458 | "widget": "ActionCard" 459 | }, 460 | "form": { 461 | "helpLink": "https://aka.ms/bfc-using-memory", 462 | "label": "Delete properties", 463 | "properties": { 464 | "properties": { 465 | "intellisenseScopes": [ 466 | "user-variables" 467 | ] 468 | } 469 | }, 470 | "subtitle": "Delete Properties" 471 | }, 472 | "menu": { 473 | "label": "Delete properties", 474 | "submenu": [ 475 | "Manage properties" 476 | ] 477 | } 478 | }, 479 | "Microsoft.DeleteProperty": { 480 | "flow": { 481 | "body": "=action.property", 482 | "widget": "ActionCard" 483 | }, 484 | "form": { 485 | "helpLink": "https://aka.ms/bfc-using-memory", 486 | "label": "Delete a property", 487 | "properties": { 488 | "property": { 489 | "intellisenseScopes": [ 490 | "user-variables" 491 | ] 492 | } 493 | }, 494 | "subtitle": "Delete Property" 495 | }, 496 | "menu": { 497 | "label": "Delete a property", 498 | "submenu": [ 499 | "Manage properties" 500 | ] 501 | } 502 | }, 503 | "Microsoft.EditActions": { 504 | "flow": { 505 | "body": "=action.changeType", 506 | "widget": "ActionCard" 507 | }, 508 | "form": { 509 | "label": "Modify active dialog", 510 | "subtitle": "Edit Actions" 511 | } 512 | }, 513 | "Microsoft.EditArray": { 514 | "flow": { 515 | "body": { 516 | "operation": "=coalesce(action.changeType, \"?\")", 517 | "resource": "=coalesce(action.itemsProperty, \"?\")", 518 | "widget": "ResourceOperation" 519 | }, 520 | "footer": { 521 | "description": "= Result", 522 | "property": "=action.resultProperty", 523 | "widget": "PropertyDescription" 524 | }, 525 | "hideFooter": "=!action.resultProperty", 526 | "widget": "ActionCard" 527 | }, 528 | "form": { 529 | "helpLink": "https://aka.ms/bfc-using-memory", 530 | "label": "Edit an array property", 531 | "properties": { 532 | "itemsProperty": { 533 | "intellisenseScopes": [ 534 | "user-variables" 535 | ] 536 | }, 537 | "resultProperty": { 538 | "intellisenseScopes": [ 539 | "variable-scopes" 540 | ] 541 | } 542 | }, 543 | "subtitle": "Edit Array" 544 | }, 545 | "menu": { 546 | "label": "Edit an array property", 547 | "submenu": [ 548 | "Manage properties" 549 | ] 550 | } 551 | }, 552 | "Microsoft.EmitEvent": { 553 | "flow": { 554 | "body": { 555 | "description": "(Event)", 556 | "property": "=coalesce(action.eventName, \"?\")", 557 | "widget": "PropertyDescription" 558 | }, 559 | "widget": "ActionCard" 560 | }, 561 | "form": { 562 | "helpLink": "https://aka.ms/bfc-custom-events", 563 | "label": "Emit a custom event", 564 | "subtitle": "Emit Event" 565 | }, 566 | "menu": { 567 | "label": "Emit a custom event", 568 | "submenu": [ 569 | "Access external resources" 570 | ] 571 | } 572 | }, 573 | "Microsoft.EndDialog": { 574 | "form": { 575 | "helpLink": "https://aka.ms/bfc-understanding-dialogs", 576 | "label": "End this dialog", 577 | "subtitle": "End Dialog" 578 | }, 579 | "menu": { 580 | "label": "End this dialog", 581 | "submenu": [ 582 | "Dialog management" 583 | ] 584 | } 585 | }, 586 | "Microsoft.EndTurn": { 587 | "form": { 588 | "helpLink": "https://aka.ms/bfc-understanding-dialogs", 589 | "label": "End turn", 590 | "subtitle": "End Turn" 591 | }, 592 | "menu": { 593 | "label": "End turn", 594 | "submenu": [ 595 | "Dialog management" 596 | ] 597 | } 598 | }, 599 | "Microsoft.Foreach": { 600 | "flow": { 601 | "loop": { 602 | "body": "=concat(\"Each value in \", coalesce(action.itemsProperty, \"?\"))", 603 | "widget": "ActionCard" 604 | }, 605 | "nowrap": true, 606 | "widget": "ForeachWidget" 607 | }, 608 | "form": { 609 | "helpLink": "https://aka.ms/bfc-controlling-conversation-flow", 610 | "hidden": [ 611 | "actions" 612 | ], 613 | "label": "Loop: For each item", 614 | "order": [ 615 | "itemsProperty", 616 | "*" 617 | ], 618 | "properties": { 619 | "index": { 620 | "intellisenseScopes": [ 621 | "variable-scopes" 622 | ] 623 | }, 624 | "itemsProperty": { 625 | "intellisenseScopes": [ 626 | "user-variables" 627 | ] 628 | }, 629 | "value": { 630 | "intellisenseScopes": [ 631 | "variable-scopes" 632 | ] 633 | } 634 | }, 635 | "subtitle": "For Each" 636 | }, 637 | "menu": { 638 | "label": "Loop: For each item", 639 | "submenu": [ 640 | "Looping" 641 | ] 642 | } 643 | }, 644 | "Microsoft.ForeachPage": { 645 | "flow": { 646 | "loop": { 647 | "body": "=concat(\"Each page of \", coalesce(action.pageSize, \"?\"), \" in \", coalesce(action.page, \"?\"))", 648 | "widget": "ActionCard" 649 | }, 650 | "nowrap": true, 651 | "widget": "ForeachWidget" 652 | }, 653 | "form": { 654 | "helpLink": "https://aka.ms/bfc-controlling-conversation-flow", 655 | "hidden": [ 656 | "actions" 657 | ], 658 | "label": "Loop: For each page (multiple items)", 659 | "order": [ 660 | "itemsProperty", 661 | "pageSize", 662 | "*" 663 | ], 664 | "properties": { 665 | "itemsProperty": { 666 | "intellisenseScopes": [ 667 | "user-variables" 668 | ] 669 | }, 670 | "page": { 671 | "intellisenseScopes": [ 672 | "variable-scopes" 673 | ] 674 | }, 675 | "pageIndex": { 676 | "intellisenseScopes": [ 677 | "variable-scopes" 678 | ] 679 | } 680 | }, 681 | "subtitle": "For Each Page" 682 | }, 683 | "menu": { 684 | "label": "Loop: For each page (multiple items)", 685 | "submenu": [ 686 | "Looping" 687 | ] 688 | } 689 | }, 690 | "Microsoft.GetActivityMembers": { 691 | "flow": { 692 | "body": { 693 | "description": "= ActivityId", 694 | "property": "=coalesce(action.activityId, \"?\")", 695 | "widget": "PropertyDescription" 696 | }, 697 | "footer": { 698 | "description": "= Result property", 699 | "property": "=coalesce(action.property, \"?\")", 700 | "widget": "PropertyDescription" 701 | }, 702 | "widget": "ActionCard" 703 | }, 704 | "menu": { 705 | "label": "Get activity members", 706 | "submenu": [ 707 | "Manage properties" 708 | ] 709 | } 710 | }, 711 | "Microsoft.GetConversationMembers": { 712 | "flow": { 713 | "footer": { 714 | "description": "= Result property", 715 | "property": "=action.property", 716 | "widget": "PropertyDescription" 717 | }, 718 | "widget": "ActionCard" 719 | }, 720 | "menu": { 721 | "label": "Get conversation members", 722 | "submenu": [ 723 | "Manage properties" 724 | ] 725 | } 726 | }, 727 | "Microsoft.GetConversationReference": { 728 | "menu": { 729 | "label": "Get conversation reference", 730 | "submenu": [ 731 | "Dialog management" 732 | ] 733 | } 734 | }, 735 | "Microsoft.GotoAction": { 736 | "menu": { 737 | "label": "Go to action", 738 | "submenu": [ 739 | "Dialog management" 740 | ] 741 | } 742 | }, 743 | "Microsoft.HttpRequest": { 744 | "flow": { 745 | "body": { 746 | "operation": "=action.method", 747 | "resource": "=action.url", 748 | "singleline": true, 749 | "widget": "ResourceOperation" 750 | }, 751 | "footer": { 752 | "description": "= Result property", 753 | "property": "=action.resultProperty", 754 | "widget": "PropertyDescription" 755 | }, 756 | "hideFooter": "=!action.resultProperty", 757 | "widget": "ActionCard" 758 | }, 759 | "form": { 760 | "helpLink": "https://aka.ms/bfc-using-http", 761 | "label": "Send an HTTP request", 762 | "order": [ 763 | "method", 764 | "url", 765 | "body", 766 | "headers", 767 | "*" 768 | ], 769 | "properties": { 770 | "resultProperty": { 771 | "intellisenseScopes": [ 772 | "variable-scopes" 773 | ] 774 | } 775 | }, 776 | "subtitle": "HTTP Request" 777 | }, 778 | "menu": { 779 | "label": "Send an HTTP request", 780 | "submenu": [ 781 | "Access external resources" 782 | ] 783 | } 784 | }, 785 | "Microsoft.IfCondition": { 786 | "flow": { 787 | "judgement": { 788 | "body": "=coalesce(action.condition, \"\")", 789 | "widget": "ActionCard" 790 | }, 791 | "nowrap": true, 792 | "widget": "IfConditionWidget" 793 | }, 794 | "form": { 795 | "helpLink": "https://aka.ms/bfc-controlling-conversation-flow", 796 | "hidden": [ 797 | "actions", 798 | "elseActions" 799 | ], 800 | "label": "Branch: If/Else", 801 | "subtitle": "If Condition" 802 | }, 803 | "menu": { 804 | "label": "Branch: If/else", 805 | "submenu": [ 806 | "Create a condition" 807 | ] 808 | } 809 | }, 810 | "Microsoft.LogAction": { 811 | "form": { 812 | "helpLink": "https://aka.ms/composer-telemetry", 813 | "label": "Log to console", 814 | "subtitle": "Log Action" 815 | }, 816 | "menu": { 817 | "label": "Log to console", 818 | "submenu": [ 819 | "Debugging options" 820 | ] 821 | } 822 | }, 823 | "Microsoft.NumberInput": { 824 | "flow": { 825 | "body": "=action.prompt", 826 | "botAsks": { 827 | "body": { 828 | "defaultContent": "", 829 | "field": "prompt", 830 | "widget": "LgWidget" 831 | }, 832 | "header": { 833 | "colors": { 834 | "icon": "#5C2E91", 835 | "theme": "#EEEAF4" 836 | }, 837 | "icon": "MessageBot", 838 | "widget": "ActionHeader" 839 | }, 840 | "widget": "ActionCard" 841 | }, 842 | "nowrap": true, 843 | "userInput": { 844 | "header": { 845 | "colors": { 846 | "icon": "#0078D4", 847 | "theme": "#E5F0FF" 848 | }, 849 | "disableSDKTitle": true, 850 | "icon": "User", 851 | "menu": "none", 852 | "widget": "ActionHeader" 853 | }, 854 | "widget": "ActionCard" 855 | }, 856 | "widget": "PromptWidget" 857 | }, 858 | "form": { 859 | "helpLink": "https://aka.ms/bfc-ask-for-user-input", 860 | "label": "Prompt for a number", 861 | "properties": { 862 | "property": { 863 | "intellisenseScopes": [ 864 | "variable-scopes" 865 | ] 866 | } 867 | }, 868 | "subtitle": "Number Input" 869 | }, 870 | "menu": { 871 | "label": "Number", 872 | "submenu": [ 873 | "Ask a question" 874 | ] 875 | } 876 | }, 877 | "Microsoft.OAuthInput": { 878 | "flow": { 879 | "body": { 880 | "operation": "Connection", 881 | "resource": "=coalesce(action.connectionName, \"?\")", 882 | "singleline": true, 883 | "widget": "ResourceOperation" 884 | }, 885 | "footer": { 886 | "description": "= Token property", 887 | "property": "=action.property", 888 | "widget": "PropertyDescription" 889 | }, 890 | "hideFooter": "=!action.property", 891 | "widget": "ActionCard" 892 | }, 893 | "form": { 894 | "helpLink": "https://aka.ms/bfc-using-oauth", 895 | "label": "OAuth login", 896 | "order": [ 897 | "connectionName", 898 | "*" 899 | ], 900 | "subtitle": "OAuth Input" 901 | }, 902 | "menu": [ 903 | { 904 | "label": "OAuth login", 905 | "submenu": [ 906 | "Ask a question" 907 | ] 908 | }, 909 | { 910 | "label": "OAuth login", 911 | "submenu": [ 912 | "Access external resources" 913 | ] 914 | } 915 | ] 916 | }, 917 | "Microsoft.OnActivity": { 918 | "form": { 919 | "hidden": [ 920 | "actions" 921 | ], 922 | "label": "Activities", 923 | "order": [ 924 | "condition", 925 | "*" 926 | ], 927 | "subtitle": "Activity received" 928 | }, 929 | "trigger": { 930 | "label": "Activities (Activity received)", 931 | "order": 5.1, 932 | "submenu": { 933 | "label": "Activities", 934 | "placeholder": "Select an activity type", 935 | "prompt": "Which activity type?" 936 | } 937 | } 938 | }, 939 | "Microsoft.OnAssignEntity": { 940 | "form": { 941 | "hidden": [ 942 | "actions" 943 | ], 944 | "label": "Handle a condition when an entity is assigned", 945 | "order": [ 946 | "condition", 947 | "*" 948 | ], 949 | "subtitle": "EntityAssigned activity" 950 | } 951 | }, 952 | "Microsoft.OnBeginDialog": { 953 | "form": { 954 | "hidden": [ 955 | "actions" 956 | ], 957 | "label": "Dialog started", 958 | "order": [ 959 | "condition", 960 | "*" 961 | ], 962 | "subtitle": "Begin dialog event" 963 | }, 964 | "trigger": { 965 | "label": "Dialog started (Begin dialog event)", 966 | "order": 4.1, 967 | "submenu": { 968 | "label": "Dialog events", 969 | "placeholder": "Select an event type", 970 | "prompt": "Which event?" 971 | } 972 | } 973 | }, 974 | "Microsoft.OnCancelDialog": { 975 | "form": { 976 | "hidden": [ 977 | "actions" 978 | ], 979 | "label": "Dialog cancelled", 980 | "order": [ 981 | "condition", 982 | "*" 983 | ], 984 | "subtitle": "Cancel dialog event" 985 | }, 986 | "trigger": { 987 | "label": "Dialog cancelled (Cancel dialog event)", 988 | "order": 4.2, 989 | "submenu": "Dialog events" 990 | } 991 | }, 992 | "Microsoft.OnChooseEntity": { 993 | "form": { 994 | "hidden": [ 995 | "actions" 996 | ], 997 | "order": [ 998 | "condition", 999 | "*" 1000 | ] 1001 | } 1002 | }, 1003 | "Microsoft.OnChooseIntent": { 1004 | "form": { 1005 | "hidden": [ 1006 | "actions" 1007 | ], 1008 | "order": [ 1009 | "condition", 1010 | "*" 1011 | ] 1012 | }, 1013 | "trigger": { 1014 | "label": "Duplicated intents recognized", 1015 | "order": 6 1016 | } 1017 | }, 1018 | "Microsoft.OnCommandActivity": { 1019 | "form": { 1020 | "hidden": [ 1021 | "actions" 1022 | ], 1023 | "label": "Command received", 1024 | "order": [ 1025 | "condition", 1026 | "*" 1027 | ], 1028 | "subtitle": "Command activity received" 1029 | }, 1030 | "trigger": { 1031 | "label": "Command received (Command activity received)", 1032 | "order": 5.81, 1033 | "submenu": "Activities" 1034 | } 1035 | }, 1036 | "Microsoft.OnCommandResultActivity": { 1037 | "form": { 1038 | "hidden": [ 1039 | "actions" 1040 | ], 1041 | "label": "Command Result received", 1042 | "order": [ 1043 | "condition", 1044 | "*" 1045 | ], 1046 | "subtitle": "Command Result activity received" 1047 | }, 1048 | "trigger": { 1049 | "label": "Command Result received (Command Result activity received)", 1050 | "order": 5.81, 1051 | "submenu": "Activities" 1052 | } 1053 | }, 1054 | "Microsoft.OnCondition": { 1055 | "form": { 1056 | "hidden": [ 1057 | "actions" 1058 | ], 1059 | "label": "Handle a condition", 1060 | "order": [ 1061 | "condition", 1062 | "*" 1063 | ], 1064 | "subtitle": "Condition" 1065 | } 1066 | }, 1067 | "Microsoft.OnContinueConversation": { 1068 | "form": { 1069 | "hidden": [ 1070 | "actions" 1071 | ] 1072 | }, 1073 | "trigger": { 1074 | "submenu": "Activities" 1075 | } 1076 | }, 1077 | "Microsoft.OnConversationUpdateActivity": { 1078 | "form": { 1079 | "description": "Handle the events fired when a user begins a new conversation with the bot.", 1080 | "helpLink": "https://aka.ms/bf-composer-docs-conversation-update-activity", 1081 | "hidden": [ 1082 | "actions" 1083 | ], 1084 | "label": "Greeting", 1085 | "order": [ 1086 | "condition", 1087 | "*" 1088 | ], 1089 | "subtitle": "ConversationUpdate activity" 1090 | }, 1091 | "trigger": { 1092 | "label": "Greeting (ConversationUpdate activity)", 1093 | "order": 5.2, 1094 | "submenu": "Activities" 1095 | } 1096 | }, 1097 | "Microsoft.OnDialogEvent": { 1098 | "form": { 1099 | "hidden": [ 1100 | "actions" 1101 | ], 1102 | "label": "Dialog events", 1103 | "order": [ 1104 | "condition", 1105 | "*" 1106 | ], 1107 | "subtitle": "Dialog event" 1108 | }, 1109 | "trigger": { 1110 | "label": "Custom events", 1111 | "order": 7 1112 | } 1113 | }, 1114 | "Microsoft.OnEndOfActions": { 1115 | "form": { 1116 | "hidden": [ 1117 | "actions" 1118 | ], 1119 | "label": "Handle a condition when actions have ended", 1120 | "order": [ 1121 | "condition", 1122 | "*" 1123 | ], 1124 | "subtitle": "EndOfActions activity" 1125 | } 1126 | }, 1127 | "Microsoft.OnEndOfConversationActivity": { 1128 | "form": { 1129 | "hidden": [ 1130 | "actions" 1131 | ], 1132 | "label": "Conversation ended", 1133 | "order": [ 1134 | "condition", 1135 | "*" 1136 | ], 1137 | "subtitle": "EndOfConversation activity" 1138 | }, 1139 | "trigger": { 1140 | "label": "Conversation ended (EndOfConversation activity)", 1141 | "order": 5.3, 1142 | "submenu": "Activities" 1143 | } 1144 | }, 1145 | "Microsoft.OnError": { 1146 | "form": { 1147 | "hidden": [ 1148 | "actions" 1149 | ], 1150 | "label": "Error occurred", 1151 | "order": [ 1152 | "condition", 1153 | "*" 1154 | ], 1155 | "subtitle": "Error event" 1156 | }, 1157 | "trigger": { 1158 | "label": "Error occurred (Error event)", 1159 | "order": 4.3, 1160 | "submenu": "Dialog events" 1161 | } 1162 | }, 1163 | "Microsoft.OnEventActivity": { 1164 | "form": { 1165 | "hidden": [ 1166 | "actions" 1167 | ], 1168 | "label": "Event received", 1169 | "order": [ 1170 | "condition", 1171 | "*" 1172 | ], 1173 | "subtitle": "Event activity" 1174 | }, 1175 | "trigger": { 1176 | "label": "Event received (Event activity)", 1177 | "order": 5.4, 1178 | "submenu": "Activities" 1179 | } 1180 | }, 1181 | "Microsoft.OnHandoffActivity": { 1182 | "form": { 1183 | "hidden": [ 1184 | "actions" 1185 | ], 1186 | "label": "Handover to human", 1187 | "order": [ 1188 | "condition", 1189 | "*" 1190 | ], 1191 | "subtitle": "Handoff activity" 1192 | }, 1193 | "trigger": { 1194 | "label": "Handover to human (Handoff activity)", 1195 | "order": 5.5, 1196 | "submenu": "Activities" 1197 | } 1198 | }, 1199 | "Microsoft.OnInstallationUpdateActivity": { 1200 | "form": { 1201 | "hidden": [ 1202 | "actions" 1203 | ], 1204 | "label": "Installation updated", 1205 | "order": [ 1206 | "condition", 1207 | "*" 1208 | ], 1209 | "subtitle": "Installation updated activity" 1210 | } 1211 | }, 1212 | "Microsoft.OnIntent": { 1213 | "form": { 1214 | "hidden": [ 1215 | "actions" 1216 | ], 1217 | "label": "Intent recognized", 1218 | "order": [ 1219 | "intent", 1220 | "condition", 1221 | "entities", 1222 | "*" 1223 | ], 1224 | "subtitle": "Intent recognized" 1225 | }, 1226 | "trigger": { 1227 | "label": "Intent recognized", 1228 | "order": 1 1229 | } 1230 | }, 1231 | "Microsoft.OnInvokeActivity": { 1232 | "form": { 1233 | "hidden": [ 1234 | "actions" 1235 | ], 1236 | "label": "Conversation invoked", 1237 | "order": [ 1238 | "condition", 1239 | "*" 1240 | ], 1241 | "subtitle": "Invoke activity" 1242 | }, 1243 | "trigger": { 1244 | "label": "Conversation invoked (Invoke activity)", 1245 | "order": 5.6, 1246 | "submenu": "Activities" 1247 | } 1248 | }, 1249 | "Microsoft.OnMessageActivity": { 1250 | "form": { 1251 | "hidden": [ 1252 | "actions" 1253 | ], 1254 | "label": "Message received", 1255 | "order": [ 1256 | "condition", 1257 | "*" 1258 | ], 1259 | "subtitle": "Message activity received" 1260 | }, 1261 | "trigger": { 1262 | "label": "Message received (Message activity received)", 1263 | "order": 5.81, 1264 | "submenu": "Activities" 1265 | } 1266 | }, 1267 | "Microsoft.OnMessageDeleteActivity": { 1268 | "form": { 1269 | "hidden": [ 1270 | "actions" 1271 | ], 1272 | "label": "Message deleted", 1273 | "order": [ 1274 | "condition", 1275 | "*" 1276 | ], 1277 | "subtitle": "Message deleted activity" 1278 | }, 1279 | "trigger": { 1280 | "label": "Message deleted (Message deleted activity)", 1281 | "order": 5.82, 1282 | "submenu": "Activities" 1283 | } 1284 | }, 1285 | "Microsoft.OnMessageReactionActivity": { 1286 | "form": { 1287 | "hidden": [ 1288 | "actions" 1289 | ], 1290 | "label": "Message reaction", 1291 | "order": [ 1292 | "condition", 1293 | "*" 1294 | ], 1295 | "subtitle": "Message reaction activity" 1296 | }, 1297 | "trigger": { 1298 | "label": "Message reaction (Message reaction activity)", 1299 | "order": 5.83, 1300 | "submenu": "Activities" 1301 | } 1302 | }, 1303 | "Microsoft.OnMessageUpdateActivity": { 1304 | "form": { 1305 | "hidden": [ 1306 | "actions" 1307 | ], 1308 | "label": "Message updated", 1309 | "order": [ 1310 | "condition", 1311 | "*" 1312 | ], 1313 | "subtitle": "Message updated activity" 1314 | }, 1315 | "trigger": { 1316 | "label": "Message updated (Message updated activity)", 1317 | "order": 5.84, 1318 | "submenu": "Activities" 1319 | } 1320 | }, 1321 | "Microsoft.OnQnAMatch": { 1322 | "trigger": { 1323 | "label": "QnA Intent recognized", 1324 | "order": 2 1325 | } 1326 | }, 1327 | "Microsoft.OnRepromptDialog": { 1328 | "form": { 1329 | "hidden": [ 1330 | "actions" 1331 | ], 1332 | "label": "Re-prompt for input", 1333 | "order": [ 1334 | "condition", 1335 | "*" 1336 | ], 1337 | "subtitle": "Reprompt dialog event" 1338 | }, 1339 | "trigger": { 1340 | "label": "Re-prompt for input (Reprompt dialog event)", 1341 | "order": 4.4, 1342 | "submenu": "Dialog events" 1343 | } 1344 | }, 1345 | "Microsoft.OnTypingActivity": { 1346 | "form": { 1347 | "hidden": [ 1348 | "actions" 1349 | ], 1350 | "label": "User is typing", 1351 | "order": [ 1352 | "condition", 1353 | "*" 1354 | ], 1355 | "subtitle": "Typing activity" 1356 | }, 1357 | "trigger": { 1358 | "label": "User is typing (Typing activity)", 1359 | "order": 5.7, 1360 | "submenu": "Activities" 1361 | } 1362 | }, 1363 | "Microsoft.OnUnknownIntent": { 1364 | "form": { 1365 | "hidden": [ 1366 | "actions" 1367 | ], 1368 | "label": "Unknown intent", 1369 | "order": [ 1370 | "condition", 1371 | "*" 1372 | ], 1373 | "subtitle": "Unknown intent recognized" 1374 | }, 1375 | "trigger": { 1376 | "label": "Unknown intent", 1377 | "order": 3 1378 | } 1379 | }, 1380 | "Microsoft.QnAMakerDialog": { 1381 | "flow": { 1382 | "body": "=action.hostname", 1383 | "widget": "ActionCard" 1384 | }, 1385 | "menu": { 1386 | "label": "Connect to QnA Knowledgebase", 1387 | "submenu": [ 1388 | "Access external resources" 1389 | ] 1390 | } 1391 | }, 1392 | "Microsoft.RegexRecognizer": { 1393 | "form": { 1394 | "hidden": [ 1395 | "entities" 1396 | ] 1397 | } 1398 | }, 1399 | "Microsoft.RepeatDialog": { 1400 | "form": { 1401 | "helpLink": "https://aka.ms/bfc-understanding-dialogs", 1402 | "label": "Repeat this dialog", 1403 | "order": [ 1404 | "options", 1405 | "*" 1406 | ], 1407 | "subtitle": "Repeat Dialog" 1408 | }, 1409 | "menu": { 1410 | "label": "Repeat this dialog", 1411 | "submenu": [ 1412 | "Dialog management" 1413 | ] 1414 | } 1415 | }, 1416 | "Microsoft.ReplaceDialog": { 1417 | "flow": { 1418 | "body": { 1419 | "dialog": "=action.dialog", 1420 | "widget": "DialogRef" 1421 | }, 1422 | "widget": "ActionCard" 1423 | }, 1424 | "form": { 1425 | "helpLink": "https://aka.ms/bfc-understanding-dialogs", 1426 | "label": "Replace this dialog", 1427 | "order": [ 1428 | "dialog", 1429 | "options", 1430 | "*" 1431 | ], 1432 | "subtitle": "Replace Dialog" 1433 | }, 1434 | "menu": { 1435 | "label": "Replace this dialog", 1436 | "submenu": [ 1437 | "Dialog management" 1438 | ] 1439 | } 1440 | }, 1441 | "Microsoft.SendActivity": { 1442 | "flow": { 1443 | "body": { 1444 | "field": "activity", 1445 | "widget": "LgWidget" 1446 | }, 1447 | "header": { 1448 | "colors": { 1449 | "icon": "#5C2E91", 1450 | "theme": "#EEEAF4" 1451 | }, 1452 | "icon": "MessageBot", 1453 | "widget": "ActionHeader" 1454 | }, 1455 | "widget": "ActionCard" 1456 | }, 1457 | "form": { 1458 | "helpLink": "https://aka.ms/bfc-send-activity", 1459 | "label": "Send a response", 1460 | "order": [ 1461 | "activity", 1462 | "*" 1463 | ], 1464 | "subtitle": "Send Activity" 1465 | }, 1466 | "menu": { 1467 | "label": "Send a response", 1468 | "submenu": false 1469 | } 1470 | }, 1471 | "Microsoft.SendHandoffActivity": { 1472 | "flow": { 1473 | "widget": "ActionHeader" 1474 | }, 1475 | "form": { 1476 | "helpLink": "https://aka.ms/bfc-send-handoff-activity", 1477 | "label": "Send a handoff request", 1478 | "subtitle": "Send Handoff Activity" 1479 | }, 1480 | "menu": { 1481 | "label": "Send Handoff Event", 1482 | "submenu": [ 1483 | "Access external resources" 1484 | ] 1485 | } 1486 | }, 1487 | "Microsoft.SetProperties": { 1488 | "flow": { 1489 | "body": { 1490 | "items": "=foreach(action.assignments, x => concat(coalesce(x.property, \"?\"), \" : \", coalesce(x.value, \"?\")))", 1491 | "widget": "ListOverview" 1492 | }, 1493 | "widget": "ActionCard" 1494 | }, 1495 | "form": { 1496 | "helpLink": "https://aka.ms/bfc-using-memory", 1497 | "label": "Set properties", 1498 | "properties": { 1499 | "assignments": { 1500 | "properties": { 1501 | "property": { 1502 | "intellisenseScopes": [ 1503 | "variable-scopes" 1504 | ] 1505 | } 1506 | } 1507 | } 1508 | }, 1509 | "subtitle": "Set Properties" 1510 | }, 1511 | "menu": { 1512 | "label": "Set properties", 1513 | "submenu": [ 1514 | "Manage properties" 1515 | ] 1516 | } 1517 | }, 1518 | "Microsoft.SetProperty": { 1519 | "flow": { 1520 | "body": "${coalesce(action.property, \"?\")} : ${coalesce(action.value, \"?\")}", 1521 | "widget": "ActionCard" 1522 | }, 1523 | "form": { 1524 | "helpLink": "https://aka.ms/bfc-using-memory", 1525 | "label": "Set a property", 1526 | "properties": { 1527 | "property": { 1528 | "intellisenseScopes": [ 1529 | "variable-scopes" 1530 | ] 1531 | } 1532 | }, 1533 | "subtitle": "Set Property" 1534 | }, 1535 | "menu": { 1536 | "label": "Set a property", 1537 | "submenu": [ 1538 | "Manage properties" 1539 | ] 1540 | } 1541 | }, 1542 | "Microsoft.SignOutUser": { 1543 | "form": { 1544 | "label": "Sign out user", 1545 | "subtitle": "Signout User" 1546 | }, 1547 | "menu": { 1548 | "label": "Sign out user", 1549 | "submenu": [ 1550 | "Access external resources" 1551 | ] 1552 | } 1553 | }, 1554 | "Microsoft.SwitchCondition": { 1555 | "flow": { 1556 | "judgement": { 1557 | "body": "=coalesce(action.condition, \"\")", 1558 | "widget": "ActionCard" 1559 | }, 1560 | "nowrap": true, 1561 | "widget": "SwitchConditionWidget" 1562 | }, 1563 | "form": { 1564 | "helpLink": "https://aka.ms/bfc-controlling-conversation-flow", 1565 | "hidden": [ 1566 | "default" 1567 | ], 1568 | "label": "Branch: Switch (multiple options)", 1569 | "properties": { 1570 | "cases": { 1571 | "hidden": [ 1572 | "actions" 1573 | ] 1574 | }, 1575 | "condition": { 1576 | "intellisenseScopes": [ 1577 | "user-variables" 1578 | ] 1579 | } 1580 | }, 1581 | "subtitle": "Switch Condition" 1582 | }, 1583 | "menu": { 1584 | "label": "Branch: Switch (multiple options)", 1585 | "submenu": [ 1586 | "Create a condition" 1587 | ] 1588 | } 1589 | }, 1590 | "Microsoft.TelemetryTrackEventAction": { 1591 | "menu": { 1592 | "label": "Emit a telemetry track event", 1593 | "submenu": [ 1594 | "Debugging options" 1595 | ] 1596 | } 1597 | }, 1598 | "Microsoft.TextInput": { 1599 | "flow": { 1600 | "body": "=action.prompt", 1601 | "botAsks": { 1602 | "body": { 1603 | "defaultContent": "", 1604 | "field": "prompt", 1605 | "widget": "LgWidget" 1606 | }, 1607 | "header": { 1608 | "colors": { 1609 | "icon": "#5C2E91", 1610 | "theme": "#EEEAF4" 1611 | }, 1612 | "icon": "MessageBot", 1613 | "widget": "ActionHeader" 1614 | }, 1615 | "widget": "ActionCard" 1616 | }, 1617 | "nowrap": true, 1618 | "userInput": { 1619 | "header": { 1620 | "colors": { 1621 | "icon": "#0078D4", 1622 | "theme": "#E5F0FF" 1623 | }, 1624 | "disableSDKTitle": true, 1625 | "icon": "User", 1626 | "menu": "none", 1627 | "widget": "ActionHeader" 1628 | }, 1629 | "widget": "ActionCard" 1630 | }, 1631 | "widget": "PromptWidget" 1632 | }, 1633 | "form": { 1634 | "helpLink": "https://aka.ms/bfc-ask-for-user-input", 1635 | "label": "Prompt for text", 1636 | "properties": { 1637 | "property": { 1638 | "intellisenseScopes": [ 1639 | "variable-scopes" 1640 | ] 1641 | } 1642 | }, 1643 | "subtitle": "Text Input" 1644 | }, 1645 | "menu": { 1646 | "label": "Text", 1647 | "submenu": [ 1648 | "Ask a question" 1649 | ] 1650 | } 1651 | }, 1652 | "Microsoft.ThrowException": { 1653 | "flow": { 1654 | "body": { 1655 | "description": "= ErrorValue", 1656 | "property": "=coalesce(action.errorValue, \"?\")", 1657 | "widget": "PropertyDescription" 1658 | }, 1659 | "widget": "ActionCard" 1660 | }, 1661 | "form": { 1662 | "label": "Throw an exception", 1663 | "subtitle": "Throw an exception" 1664 | }, 1665 | "menu": { 1666 | "label": "Throw exception", 1667 | "submenu": [ 1668 | "Debugging options" 1669 | ] 1670 | } 1671 | }, 1672 | "Microsoft.TraceActivity": { 1673 | "form": { 1674 | "helpLink": "https://aka.ms/composer-telemetry", 1675 | "label": "Emit a trace event", 1676 | "subtitle": "Trace Activity" 1677 | }, 1678 | "menu": { 1679 | "label": "Emit a trace event", 1680 | "submenu": [ 1681 | "Debugging options" 1682 | ] 1683 | } 1684 | }, 1685 | "Microsoft.UpdateActivity": { 1686 | "flow": { 1687 | "body": { 1688 | "field": "activity", 1689 | "widget": "LgWidget" 1690 | }, 1691 | "header": { 1692 | "colors": { 1693 | "icon": "#656565", 1694 | "theme": "#D7D7D7" 1695 | }, 1696 | "icon": "MessageBot", 1697 | "title": "Update activity", 1698 | "widget": "ActionHeader" 1699 | }, 1700 | "widget": "ActionCard" 1701 | }, 1702 | "form": { 1703 | "label": "Update an activity", 1704 | "subtitle": "Update Activity" 1705 | }, 1706 | "menu": { 1707 | "label": "Update an activity", 1708 | "submenu": [ 1709 | "Manage properties" 1710 | ] 1711 | } 1712 | } 1713 | } 1714 | -------------------------------------------------------------------------------- /GPTVirtualAssistant/schemas/update-schema.ps1: -------------------------------------------------------------------------------- 1 | $SCHEMA_FILE="sdk.schema" 2 | $UISCHEMA_FILE="sdk.uischema" 3 | $BACKUP_SCHEMA_FILE="sdk-backup.schema" 4 | $BACKUP_UISCHEMA_FILE="sdk-backup.uischema" 5 | 6 | Write-Host "Running schema merge." 7 | 8 | if (Test-Path $SCHEMA_FILE -PathType leaf) { Move-Item -Force -Path $SCHEMA_FILE -Destination $BACKUP_SCHEMA_FILE } 9 | if (Test-Path $UISCHEMA_FILE -PathType leaf) { Move-Item -Force -Path $UISCHEMA_FILE -Destination $BACKUP_UISCHEMA_FILE } 10 | 11 | bf dialog:merge "*.schema" "!**/sdk-backup.schema" "*.uischema" "!**/sdk-backup.uischema" "!**/sdk.override.uischema" "!**/generated" "../*.csproj" "../package.json" -o $SCHEMA_FILE 12 | 13 | if (Test-Path $SCHEMA_FILE -PathType leaf) 14 | { 15 | if (Test-Path $BACKUP_SCHEMA_FILE -PathType leaf) { Remove-Item -Force -Path $BACKUP_SCHEMA_FILE } 16 | if (Test-Path $BACKUP_UISCHEMA_FILE -PathType leaf) { Remove-Item -Force -Path $BACKUP_UISCHEMA_FILE } 17 | 18 | Write-Host "Schema merged succesfully." 19 | if (Test-Path $SCHEMA_FILE -PathType leaf) { Write-Host " Schema: $SCHEMA_FILE" } 20 | if (Test-Path $UISCHEMA_FILE -PathType leaf) { Write-Host " UI Schema: $UISCHEMA_FILE" } 21 | } 22 | else 23 | { 24 | Write-Host "Schema merge failed. Restoring previous versions." 25 | if (Test-Path $BACKUP_SCHEMA_FILE -PathType leaf) { Move-Item -Force -Path $BACKUP_SCHEMA_FILE -Destination $SCHEMA_FILE } 26 | if (Test-Path $BACKUP_UISCHEMA_FILE -PathType leaf) { Move-Item -Force -Path $BACKUP_UISCHEMA_FILE -Destination $UISCHEMA_FILE } 27 | } 28 | -------------------------------------------------------------------------------- /GPTVirtualAssistant/schemas/update-schema.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | SCHEMA_FILE=sdk.schema 3 | UISCHEMA_FILE=sdk.uischema 4 | BACKUP_SCHEMA_FILE=sdk-backup.schema 5 | BACKUP_UISCHEMA_FILE=sdk-backup.uischema 6 | 7 | while [ $# -gt 0 ]; do 8 | if [[ $1 == *"-"* ]]; then 9 | param="${1/-/}" 10 | declare $param="$2" 11 | fi 12 | shift 13 | done 14 | 15 | echo "Running schema merge." 16 | [ -f "$SCHEMA_FILE" ] && mv "./$SCHEMA_FILE" "./$BACKUP_SCHEMA_FILE" 17 | [ -f "$UISCHEMA_FILE" ] && mv "./$UISCHEMA_FILE" "./$BACKUP_UISCHEMA_FILE" 18 | 19 | bf dialog:merge "*.schema" "!**/sdk-backup.schema" "*.uischema" "!**/sdk-backup.uischema" "!**/sdk.override.uischema" "!**/generated" "../*.csproj" "../package.json" -o $SCHEMA_FILE 20 | 21 | if [ -f "$SCHEMA_FILE" ]; then 22 | rm -rf "./$BACKUP_SCHEMA_FILE" 23 | rm -rf "./$BACKUP_UISCHEMA_FILE" 24 | echo "Schema merged succesfully." 25 | [ -f "$SCHEMA_FILE" ] && echo " Schema: $SCHEMA_FILE" 26 | [ -f "$UISCHEMA_FILE" ] && echo " UI Schema: $UISCHEMA_FILE" 27 | else 28 | echo "Schema merge failed. Restoring previous versions." 29 | [ -f "$BACKUP_SCHEMA_FILE" ] && mv "./$BACKUP_SCHEMA_FILE" "./$SCHEMA_FILE" 30 | [ -f "$BACKUP_UISCHEMA_FILE" ] && mv "./$BACKUP_UISCHEMA_FILE" "./$UISCHEMA_FILE" 31 | fi 32 | -------------------------------------------------------------------------------- /GPTVirtualAssistant/scripts/DeploymentTemplates/function-template-with-preexisting-rg.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", 3 | "contentVersion": "1.0.0.0", 4 | "parameters": { 5 | "name": { 6 | "type": "string", 7 | "defaultValue": "[resourceGroup().name]" 8 | }, 9 | "appId": { 10 | "type": "string", 11 | "metadata": { 12 | "description": "Active Directory App ID, set as MicrosoftAppId in the Web App's Application Settings." 13 | } 14 | }, 15 | "appSecret": { 16 | "type": "string", 17 | "metadata": { 18 | "description": "Active Directory App Password, set as MicrosoftAppPassword in the Web App's Application Settings. Defaults to \"\"." 19 | } 20 | }, 21 | "useCosmosDb": { 22 | "type": "bool", 23 | "defaultValue": true 24 | }, 25 | "useAppInsights": { 26 | "type": "bool", 27 | "defaultValue": true 28 | }, 29 | "shouldCreateAuthoringResource": { 30 | "type": "bool", 31 | "defaultValue": true 32 | }, 33 | "shouldCreateLuisResource": { 34 | "type": "bool", 35 | "defaultValue": true 36 | }, 37 | "cosmosDbName": { 38 | "type": "string", 39 | "defaultValue": "[resourceGroup().name]" 40 | }, 41 | "botId": { 42 | "type": "string", 43 | "metadata": { 44 | "description": "The globally unique and immutable bot ID. Also used to configure the displayName of the bot, which is mutable." 45 | } 46 | }, 47 | "botSku": { 48 | "defaultValue": "F0", 49 | "type": "string", 50 | "metadata": { 51 | "description": "The pricing tier of the Bot Service Registration. Acceptable values are F0 and S1." 52 | } 53 | }, 54 | "luisAuthoringKey": { 55 | "type": "string", 56 | "defaultValue": "" 57 | }, 58 | "newAppServicePlanName": { 59 | "type": "string", 60 | "defaultValue": "[resourceGroup().name]", 61 | "metadata": { 62 | "description": "The name of the new App Service Plan." 63 | } 64 | }, 65 | "newAppServicePlanSku": { 66 | "type": "object", 67 | "defaultValue": { 68 | "name": "S1", 69 | "tier": "Standard", 70 | "size": "S1", 71 | "family": "S", 72 | "capacity": 1 73 | }, 74 | "metadata": { 75 | "description": "The SKU of the App Service Plan. Defaults to Standard values." 76 | } 77 | }, 78 | "appServicePlanLocation": { 79 | "type": "string", 80 | "metadata": { 81 | "description": "The location of the App Service Plan." 82 | } 83 | }, 84 | "existingAppServicePlan": { 85 | "type": "string", 86 | "defaultValue": "", 87 | "metadata": { 88 | "description": "Name of the existing App Service Plan used to create the Web App for the bot." 89 | } 90 | }, 91 | "newWebAppName": { 92 | "type": "string", 93 | "defaultValue": "[resourceGroup().name]", 94 | "metadata": { 95 | "description": "The globally unique name of the Web App. Defaults to the value passed in for \"botId\"." 96 | } 97 | }, 98 | "appInsightsName": { 99 | "type": "string", 100 | "defaultValue": "[resourceGroup().name]" 101 | }, 102 | "location": { 103 | "type": "string", 104 | "defaultValue": "[resourceGroup().location]" 105 | }, 106 | "appInsightsLocation": { 107 | "type": "string", 108 | "defaultValue": "[resourceGroup().location]" 109 | }, 110 | "useStorage": { 111 | "type": "bool", 112 | "defaultValue": true 113 | }, 114 | "storageAccountName": { 115 | "type": "string", 116 | "defaultValue": "[resourceGroup().name]" 117 | }, 118 | "luisServiceName": { 119 | "type": "string", 120 | "defaultValue": "[concat(resourceGroup().name, '-luis')]" 121 | }, 122 | "luisServiceAuthoringSku": { 123 | "type": "string", 124 | "defaultValue": "F0" 125 | }, 126 | "luisServiceRunTimeSku": { 127 | "type": "string", 128 | "defaultValue": "S0" 129 | }, 130 | "luisServiceLocation": { 131 | "type": "string", 132 | "defaultValue": "[resourceGroup().location]" 133 | } 134 | }, 135 | "variables": { 136 | "defaultAppServicePlanName": "[if(empty(parameters('existingAppServicePlan')), 'createNewAppServicePlan', parameters('existingAppServicePlan'))]", 137 | "useExistingAppServicePlan": "[not(equals(variables('defaultAppServicePlanName'), 'createNewAppServicePlan'))]", 138 | "servicePlanName": "[if(variables('useExistingAppServicePlan'), parameters('existingAppServicePlan'), parameters('newAppServicePlanName'))]", 139 | "resourcesLocation": "[parameters('appServicePlanLocation')]", 140 | "cosmosDbAccountName": "[toLower(take(replace(parameters('cosmosDbName'), '_', ''), 31))]", 141 | "webAppName": "[if(empty(parameters('newWebAppName')), parameters('botId'), parameters('newWebAppName'))]", 142 | "siteHost": "[concat(variables('webAppName'), '.azurewebsites.net')]", 143 | "botEndpoint": "[concat('https://', variables('siteHost'), '/api/messages')]", 144 | "storageAccountName": "[toLower(take(replace(replace(parameters('storageAccountName'), '-', ''), '_', ''), 24))]", 145 | "LuisAuthoringAccountName": "[concat(parameters('luisServiceName'), '-Authoring')]" 146 | }, 147 | "resources": [ 148 | { 149 | "comments": "Create a Web App using an App Service Plan", 150 | "type": "Microsoft.Web/sites", 151 | "apiVersion": "2015-08-01", 152 | "location": "[variables('resourcesLocation')]", 153 | "kind": "functionapp", 154 | "name": "[variables('webAppName')]", 155 | "properties": { 156 | "name": "[variables('webAppName')]", 157 | "kind": "functionapp", 158 | "httpsOnly": true 159 | }, 160 | "resources": [ 161 | { 162 | "name": "appsettings", 163 | "type": "config", 164 | "apiVersion": "2015-08-01", 165 | "dependsOn": [ 166 | "[concat('Microsoft.Web/Sites/', variables('webAppName'))]" 167 | ], 168 | "properties": { 169 | "FUNCTIONS_EXTENSION_VERSION": "~3", 170 | "FUNCTIONS_WORKER_RUNTIME": "dotnet", 171 | "APPINSIGHTS_INSTRUMENTATIONKEY": "[reference(resourceId('microsoft.insights/components/', parameters('appInsightsName')), '2015-05-01').InstrumentationKey]", 172 | "MicrosoftAppId": "[parameters('appId')]", 173 | "MicrosoftAppPassword": "[parameters('appSecret')]" 174 | } 175 | } 176 | ] 177 | }, 178 | { 179 | "comments": "CosmosDB for bot state.", 180 | "type": "Microsoft.DocumentDB/databaseAccounts", 181 | "kind": "GlobalDocumentDB", 182 | "apiVersion": "2015-04-08", 183 | "name": "[variables('cosmosDbAccountName')]", 184 | "location": "[parameters('location')]", 185 | "properties": { 186 | "databaseAccountOfferType": "Standard", 187 | "locations": [ 188 | { 189 | "locationName": "[parameters('location')]", 190 | "failoverPriority": 0 191 | } 192 | ] 193 | }, 194 | "condition": "[parameters('useCosmosDb')]" 195 | }, 196 | { 197 | "type": "Microsoft.DocumentDB/databaseAccounts/sqlDatabases", 198 | "apiVersion": "2020-03-01", 199 | "name": "[concat(variables('cosmosDbAccountName'), '/botstate-db')]", 200 | "dependsOn": [ 201 | "[resourceId('Microsoft.DocumentDB/databaseAccounts', variables('cosmosDbAccountName'))]" 202 | ], 203 | "properties": { 204 | "resource": { 205 | "id": "botstate-db" 206 | }, 207 | "options": {} 208 | }, 209 | "condition": "[parameters('useCosmosDb')]" 210 | }, 211 | { 212 | "type": "Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers", 213 | "apiVersion": "2020-03-01", 214 | "name": "[concat(variables('cosmosDbAccountName'), '/botstate-db/botstate-container')]", 215 | "dependsOn": [ 216 | "[resourceId('Microsoft.DocumentDB/databaseAccounts/sqlDatabases', variables('cosmosDbAccountName'), 'botstate-db')]", 217 | "[resourceId('Microsoft.DocumentDB/databaseAccounts', variables('cosmosDbAccountName'))]" 218 | ], 219 | "properties": { 220 | "resource": { 221 | "id": "botstate-container", 222 | "indexingPolicy": { 223 | "indexingMode": "consistent", 224 | "automatic": true, 225 | "includedPaths": [ 226 | { 227 | "path": "/*" 228 | } 229 | ], 230 | "excludedPaths": [ 231 | { 232 | "path": "/\"_etag\"/?" 233 | } 234 | ] 235 | }, 236 | "partitionKey": { 237 | "paths": [ 238 | "/id" 239 | ], 240 | "kind": "Hash" 241 | }, 242 | "conflictResolutionPolicy": { 243 | "mode": "LastWriterWins", 244 | "conflictResolutionPath": "/_ts" 245 | } 246 | }, 247 | "options": {} 248 | }, 249 | "condition": "[parameters('useCosmosDb')]" 250 | }, 251 | { 252 | "apiVersion": "2017-12-01", 253 | "type": "Microsoft.BotService/botServices", 254 | "name": "[parameters('botId')]", 255 | "location": "global", 256 | "kind": "bot", 257 | "sku": { 258 | "name": "[parameters('botSku')]" 259 | }, 260 | "properties": { 261 | "name": "[parameters('botId')]", 262 | "displayName": "[parameters('botId')]", 263 | "endpoint": "[variables('botEndpoint')]", 264 | "msaAppId": "[parameters('appId')]", 265 | "developerAppInsightsApplicationId": null, 266 | "developerAppInsightKey": null, 267 | "publishingCredentials": null, 268 | "storageResourceId": null 269 | }, 270 | "dependsOn": [ 271 | "[resourceId('Microsoft.Web/sites/', variables('webAppName'))]" 272 | ] 273 | }, 274 | { 275 | "comments": "app insights", 276 | "type": "Microsoft.Insights/components", 277 | "kind": "web", 278 | "apiVersion": "2015-05-01", 279 | "name": "[parameters('appInsightsName')]", 280 | "location": "[parameters('appInsightsLocation')]", 281 | "properties": { 282 | "Application_Type": "web" 283 | }, 284 | "condition": "[parameters('useAppInsights')]" 285 | }, 286 | { 287 | "comments": "storage account", 288 | "type": "Microsoft.Storage/storageAccounts", 289 | "kind": "StorageV2", 290 | "apiVersion": "2018-07-01", 291 | "name": "[variables('storageAccountName')]", 292 | "location": "[parameters('location')]", 293 | "sku": { 294 | "name": "Standard_LRS" 295 | }, 296 | "condition": "[parameters('useStorage')]" 297 | }, 298 | { 299 | "comments": "Cognitive service authoring key for all LUIS apps.", 300 | "apiVersion": "2017-04-18", 301 | "name": "[variables('LuisAuthoringAccountName')]", 302 | "location": "[parameters('luisServiceLocation')]", 303 | "type": "Microsoft.CognitiveServices/accounts", 304 | "kind": "LUIS.Authoring", 305 | "sku": { 306 | "name": "[parameters('luisServiceAuthoringSku')]" 307 | }, 308 | "condition": "[parameters('shouldCreateAuthoringResource')]" 309 | }, 310 | { 311 | "comments": "Cognitive service endpoint key for all LUIS apps.", 312 | "type": "Microsoft.CognitiveServices/accounts", 313 | "kind": "LUIS", 314 | "apiVersion": "2017-04-18", 315 | "name": "[parameters('luisServiceName')]", 316 | "location": "[parameters('luisServiceLocation')]", 317 | "sku": { 318 | "name": "[parameters('luisServiceRunTimeSku')]" 319 | }, 320 | "condition": "[parameters('shouldCreateLuisResource')]" 321 | } 322 | ], 323 | "outputs": { 324 | "ApplicationInsights": { 325 | "type": "object", 326 | "value": { 327 | "InstrumentationKey": "[if(parameters('useAppInsights'), reference(resourceId('Microsoft.Insights/components', parameters('appInsightsName'))).InstrumentationKey, '')]" 328 | } 329 | }, 330 | "cosmosDb": { 331 | "type": "object", 332 | "value": { 333 | "cosmosDBEndpoint": "[if(parameters('useCosmosDb'), reference(resourceId('Microsoft.DocumentDB/databaseAccounts', variables('cosmosDbAccountName'))).documentEndpoint, '')]", 334 | "authKey": "[if(parameters('useCosmosDb'), listKeys(resourceId('Microsoft.DocumentDB/databaseAccounts', variables('cosmosDbAccountName')), '2015-04-08').primaryMasterKey, '')]", 335 | "databaseId": "botstate-db", 336 | "containerId": "botstate-container" 337 | } 338 | }, 339 | "blobStorage": { 340 | "type": "object", 341 | "value": { 342 | "connectionString": "[if(parameters('useStorage'), concat('DefaultEndpointsProtocol=https;AccountName=', variables('storageAccountName'), ';AccountKey=', listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName')), '2018-07-01').keys[0].value, ';EndpointSuffix=core.windows.net'), '')]", 343 | "container": "transcripts" 344 | } 345 | }, 346 | "luis": { 347 | "type": "object", 348 | "value": { 349 | "endpointKey": "[if(parameters('shouldCreateLuisResource'), listKeys(resourceId('Microsoft.CognitiveServices/accounts', parameters('luisServiceName')),'2017-04-18').key1, '')]", 350 | "authoringKey": "[if(parameters('shouldCreateAuthoringResource'), listKeys(resourceId('Microsoft.CognitiveServices/accounts', variables('LuisAuthoringAccountName')),'2017-04-18').key1, parameters('luisAuthoringKey'))]", 351 | "region": "[parameters('luisServiceLocation')]" 352 | } 353 | } 354 | } 355 | } 356 | -------------------------------------------------------------------------------- /GPTVirtualAssistant/scripts/DeploymentTemplates/new-rg-parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#", 3 | "contentVersion": "1.0.0.0", 4 | "parameters": { 5 | "groupLocation": { 6 | "value": "" 7 | }, 8 | "groupName": { 9 | "value": "" 10 | }, 11 | "appId": { 12 | "value": "" 13 | }, 14 | "appSecret": { 15 | "value": "" 16 | }, 17 | "botId": { 18 | "value": "" 19 | }, 20 | "botSku": { 21 | "value": "" 22 | }, 23 | "newAppServicePlanName": { 24 | "value": "" 25 | }, 26 | "newAppServicePlanSku": { 27 | "value": { 28 | "name": "S1", 29 | "tier": "Standard", 30 | "size": "S1", 31 | "family": "S", 32 | "capacity": 1 33 | } 34 | }, 35 | "newAppServicePlanLocation": { 36 | "value": "" 37 | }, 38 | "newWebAppName": { 39 | "value": "" 40 | } 41 | } 42 | } -------------------------------------------------------------------------------- /GPTVirtualAssistant/scripts/DeploymentTemplates/preexisting-rg-parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#", 3 | "contentVersion": "1.0.0.0", 4 | "parameters": { 5 | "appId": { 6 | "value": "" 7 | }, 8 | "appSecret": { 9 | "value": "" 10 | }, 11 | "botId": { 12 | "value": "" 13 | }, 14 | "botSku": { 15 | "value": "" 16 | }, 17 | "newAppServicePlanName": { 18 | "value": "" 19 | }, 20 | "newAppServicePlanSku": { 21 | "value": { 22 | "name": "S1", 23 | "tier": "Standard", 24 | "size": "S1", 25 | "family": "S", 26 | "capacity": 1 27 | } 28 | }, 29 | "appServicePlanLocation": { 30 | "value": "" 31 | }, 32 | "existingAppServicePlan": { 33 | "value": "" 34 | }, 35 | "newWebAppName": { 36 | "value": "" 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /GPTVirtualAssistant/scripts/DeploymentTemplates/qna-template.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", 3 | "contentVersion": "1.0.0.0", 4 | "parameters": { 5 | "name": { 6 | "type": "string", 7 | "defaultValue": "[resourceGroup().name]" 8 | }, 9 | "newAppServicePlanName": { 10 | "type": "string", 11 | "defaultValue": "[resourceGroup().name]", 12 | "metadata": { 13 | "description": "The name of the new App Service Plan." 14 | } 15 | }, 16 | "newAppServicePlanSku": { 17 | "type": "object", 18 | "defaultValue": { 19 | "name": "S1", 20 | "tier": "Standard", 21 | "size": "S1", 22 | "family": "S", 23 | "capacity": 1 24 | }, 25 | "metadata": { 26 | "description": "The SKU of the App Service Plan. Defaults to Standard values." 27 | } 28 | }, 29 | "appServicePlanLocation": { 30 | "type": "string", 31 | "metadata": { 32 | "description": "The location of the App Service Plan." 33 | } 34 | }, 35 | "existingAppServicePlan": { 36 | "type": "string", 37 | "defaultValue": "", 38 | "metadata": { 39 | "description": "Name of the existing App Service Plan used to create the Web App for the bot." 40 | } 41 | }, 42 | "appInsightsName": { 43 | "type": "string", 44 | "defaultValue": "[resourceGroup().name]" 45 | }, 46 | "appInsightsLocation": { 47 | "type": "string", 48 | "defaultValue": "[resourceGroup().location]" 49 | }, 50 | "qnaMakerServiceName": { 51 | "type": "string", 52 | "defaultValue": "[concat(parameters('name'), '-qna')]" 53 | }, 54 | "qnaMakerServiceSku": { 55 | "type": "string", 56 | "defaultValue": "S0" 57 | }, 58 | "qnaMakerServiceLocation": { 59 | "type": "string", 60 | "defaultValue": "westus" 61 | }, 62 | "qnaMakerSearchName": { 63 | "type": "string", 64 | "defaultValue": "[concat(parameters('name'), '-search')]" 65 | }, 66 | "qnaMakerSearchSku": { 67 | "type": "string", 68 | "defaultValue": "standard" 69 | }, 70 | "qnaMakerSearchLocation": { 71 | "type": "string", 72 | "defaultValue": "[resourceGroup().location]" 73 | }, 74 | "qnaMakerWebAppName": { 75 | "type": "string", 76 | "defaultValue": "[concat(parameters('name'), '-qnahost')]" 77 | }, 78 | "qnaMakerWebAppLocation": { 79 | "type": "string", 80 | "defaultValue": "[resourceGroup().location]" 81 | } 82 | }, 83 | "variables": { 84 | "defaultAppServicePlanName": "[if(empty(parameters('existingAppServicePlan')), 'createNewAppServicePlan', parameters('existingAppServicePlan'))]", 85 | "useExistingAppServicePlan": "[not(equals(variables('defaultAppServicePlanName'), 'createNewAppServicePlan'))]", 86 | "servicePlanName": "[if(variables('useExistingAppServicePlan'), parameters('existingAppServicePlan'), parameters('newAppServicePlanName'))]", 87 | "resourcesLocation": "[parameters('appServicePlanLocation')]", 88 | "qnaMakerSearchName": "[toLower(replace(parameters('qnaMakerSearchName'), '_', ''))]", 89 | "qnaMakerWebAppName": "[replace(parameters('qnaMakerWebAppName'), '_', '')]" 90 | }, 91 | "resources": [ 92 | { 93 | "apiVersion": "2018-02-01", 94 | "name": "1d41002f-62a1-49f3-bd43-2f3f32a19cbb", 95 | "type": "Microsoft.Resources/deployments", 96 | "properties": { 97 | "mode": "Incremental", 98 | "template": { 99 | "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", 100 | "contentVersion": "1.0.0.0", 101 | "resources": [] 102 | } 103 | } 104 | }, 105 | { 106 | "comments": "Create a new App Service Plan if no existing App Service Plan name was passed in.", 107 | "type": "Microsoft.Web/serverfarms", 108 | "condition": "[not(variables('useExistingAppServicePlan'))]", 109 | "name": "[variables('servicePlanName')]", 110 | "apiVersion": "2018-02-01", 111 | "location": "[variables('resourcesLocation')]", 112 | "sku": "[parameters('newAppServicePlanSku')]", 113 | "properties": { 114 | "name": "[variables('servicePlanName')]" 115 | } 116 | }, 117 | { 118 | "comments": "app insights", 119 | "type": "Microsoft.Insights/components", 120 | "kind": "web", 121 | "apiVersion": "2015-05-01", 122 | "name": "[parameters('appInsightsName')]", 123 | "location": "[parameters('appInsightsLocation')]", 124 | "properties": { 125 | "Application_Type": "web" 126 | } 127 | }, 128 | { 129 | "comments": "Cognitive service key for all QnA Maker knowledgebases.", 130 | "type": "Microsoft.CognitiveServices/accounts", 131 | "kind": "QnAMaker", 132 | "apiVersion": "2017-04-18", 133 | "name": "[parameters('qnaMakerServiceName')]", 134 | "location": "[parameters('qnaMakerServiceLocation')]", 135 | "sku": { 136 | "name": "[parameters('qnaMakerServiceSku')]" 137 | }, 138 | "properties": { 139 | "apiProperties": { 140 | "qnaRuntimeEndpoint": "[concat('https://',reference(resourceId('Microsoft.Web/sites', variables('qnaMakerWebAppName'))).hostNames[0])]" 141 | } 142 | }, 143 | "dependsOn": [ 144 | "[resourceId('Microsoft.Web/Sites', variables('qnaMakerWebAppName'))]", 145 | "[resourceId('Microsoft.Search/searchServices/', variables('qnaMakerSearchName'))]", 146 | "[resourceId('microsoft.insights/components/', parameters('appInsightsName'))]" 147 | ] 148 | }, 149 | { 150 | "comments": "Search service for QnA Maker service.", 151 | "type": "Microsoft.Search/searchServices", 152 | "apiVersion": "2015-08-19", 153 | "name": "[variables('qnaMakerSearchName')]", 154 | "location": "[parameters('qnaMakerSearchLocation')]", 155 | "sku": { 156 | "name": "[parameters('qnaMakerSearchSku')]" 157 | }, 158 | "properties": { 159 | "replicaCount": 1, 160 | "partitionCount": 1, 161 | "hostingMode": "default" 162 | } 163 | }, 164 | { 165 | "comments": "Web app for QnA Maker service.", 166 | "type": "Microsoft.Web/sites", 167 | "apiVersion": "2016-08-01", 168 | "name": "[variables('qnaMakerWebAppName')]", 169 | "location": "[parameters('qnaMakerWebAppLocation')]", 170 | "properties": { 171 | "enabled": true, 172 | "name": "[variables('qnaMakerWebAppName')]", 173 | "hostingEnvironment": "", 174 | "serverFarmId": "[concat('/subscriptions/', Subscription().SubscriptionId,'/resourcegroups/', resourceGroup().name, '/providers/Microsoft.Web/serverfarms/', variables('servicePlanName'))]", 175 | "siteConfig": { 176 | "cors": { 177 | "allowedOrigins": ["*"] 178 | } 179 | } 180 | }, 181 | "dependsOn": ["[resourceId('Microsoft.Web/serverfarms/', variables('servicePlanName'))]"], 182 | "resources": [ 183 | { 184 | "apiVersion": "2016-08-01", 185 | "name": "appsettings", 186 | "type": "config", 187 | "dependsOn": [ 188 | "[resourceId('Microsoft.Web/Sites', variables('qnaMakerWebAppName'))]", 189 | "[resourceId('Microsoft.Insights/components', parameters('appInsightsName'))]", 190 | "[resourceId('Microsoft.Search/searchServices/', variables('qnaMakerSearchName'))]" 191 | ], 192 | "properties": { 193 | "AzureSearchName": "[variables('qnaMakerSearchName')]", 194 | "AzureSearchAdminKey": "[listAdminKeys(resourceId('Microsoft.Search/searchServices/', variables('qnaMakerSearchName')), '2015-08-19').primaryKey]", 195 | "UserAppInsightsKey": "[reference(resourceId('Microsoft.Insights/components/', parameters('appInsightsName')), '2015-05-01').InstrumentationKey]", 196 | "UserAppInsightsName": "[parameters('appInsightsName')]", 197 | "UserAppInsightsAppId": "[reference(resourceId('Microsoft.Insights/components/', parameters('appInsightsName')), '2015-05-01').AppId]", 198 | "PrimaryEndpointKey": "[concat(variables('qnaMakerWebAppName'), '-PrimaryEndpointKey')]", 199 | "SecondaryEndpointKey": "[concat(variables('qnaMakerWebAppName'), '-SecondaryEndpointKey')]", 200 | "DefaultAnswer": "No good match found in KB.", 201 | "EnableMultipleTestIndex": "true", 202 | "QNAMAKER_EXTENSION_VERSION": "latest" 203 | } 204 | } 205 | ] 206 | } 207 | ], 208 | "outputs": { 209 | "qna": { 210 | "type": "object", 211 | "value": { 212 | "endpoint": "[concat('https://', reference(resourceId('Microsoft.Web/sites', variables('qnaMakerWebAppName'))).hostNames[0])]", 213 | "subscriptionKey": "[listKeys(resourceId('Microsoft.CognitiveServices/accounts', parameters('qnaMakerServiceName')),'2017-04-18').key1]" 214 | } 215 | } 216 | } 217 | } 218 | -------------------------------------------------------------------------------- /GPTVirtualAssistant/scripts/DeploymentTemplates/template-with-new-rg.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", 3 | "contentVersion": "1.0.0.0", 4 | "parameters": { 5 | "groupLocation": { 6 | "type": "string", 7 | "metadata": { 8 | "description": "Specifies the location of the Resource Group." 9 | } 10 | }, 11 | "groupName": { 12 | "type": "string", 13 | "metadata": { 14 | "description": "Specifies the name of the Resource Group." 15 | } 16 | }, 17 | "appId": { 18 | "type": "string", 19 | "metadata": { 20 | "description": "Active Directory App ID, set as MicrosoftAppId in the Web App's Application Settings." 21 | } 22 | }, 23 | "appSecret": { 24 | "type": "string", 25 | "metadata": { 26 | "description": "Active Directory App Password, set as MicrosoftAppPassword in the Web App's Application Settings." 27 | } 28 | }, 29 | "botId": { 30 | "type": "string", 31 | "metadata": { 32 | "description": "The globally unique and immutable bot ID. Also used to configure the displayName of the bot, which is mutable." 33 | } 34 | }, 35 | "botSku": { 36 | "type": "string", 37 | "metadata": { 38 | "description": "The pricing tier of the Bot Service Registration. Acceptable values are F0 and S1." 39 | } 40 | }, 41 | "newAppServicePlanName": { 42 | "type": "string", 43 | "metadata": { 44 | "description": "The name of the App Service Plan." 45 | } 46 | }, 47 | "newAppServicePlanSku": { 48 | "type": "object", 49 | "defaultValue": { 50 | "name": "S1", 51 | "tier": "Standard", 52 | "size": "S1", 53 | "family": "S", 54 | "capacity": 1 55 | }, 56 | "metadata": { 57 | "description": "The SKU of the App Service Plan. Defaults to Standard values." 58 | } 59 | }, 60 | "newAppServicePlanLocation": { 61 | "type": "string", 62 | "metadata": { 63 | "description": "The location of the App Service Plan. Defaults to \"westus\"." 64 | } 65 | }, 66 | "newWebAppName": { 67 | "type": "string", 68 | "defaultValue": "", 69 | "metadata": { 70 | "description": "The globally unique name of the Web App. Defaults to the value passed in for \"botId\"." 71 | } 72 | } 73 | }, 74 | "variables": { 75 | "appServicePlanName": "[parameters('newAppServicePlanName')]", 76 | "resourcesLocation": "[parameters('newAppServicePlanLocation')]", 77 | "webAppName": "[if(empty(parameters('newWebAppName')), parameters('botId'), parameters('newWebAppName'))]", 78 | "siteHost": "[concat(variables('webAppName'), '.azurewebsites.net')]", 79 | "botEndpoint": "[concat('https://', variables('siteHost'), '/api/messages')]" 80 | }, 81 | "resources": [ 82 | { 83 | "name": "[parameters('groupName')]", 84 | "type": "Microsoft.Resources/resourceGroups", 85 | "apiVersion": "2018-05-01", 86 | "location": "[parameters('groupLocation')]", 87 | "properties": { 88 | } 89 | }, 90 | { 91 | "type": "Microsoft.Resources/deployments", 92 | "apiVersion": "2018-05-01", 93 | "name": "storageDeployment", 94 | "resourceGroup": "[parameters('groupName')]", 95 | "dependsOn": [ 96 | "[resourceId('Microsoft.Resources/resourceGroups/', parameters('groupName'))]" 97 | ], 98 | "properties": { 99 | "mode": "Incremental", 100 | "template": { 101 | "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", 102 | "contentVersion": "1.0.0.0", 103 | "parameters": {}, 104 | "variables": {}, 105 | "resources": [ 106 | { 107 | "comments": "Create a new App Service Plan", 108 | "type": "Microsoft.Web/serverfarms", 109 | "name": "[variables('appServicePlanName')]", 110 | "apiVersion": "2018-02-01", 111 | "location": "[variables('resourcesLocation')]", 112 | "sku": "[parameters('newAppServicePlanSku')]", 113 | "properties": { 114 | "name": "[variables('appServicePlanName')]" 115 | } 116 | }, 117 | { 118 | "comments": "Create a Web App using the new App Service Plan", 119 | "type": "Microsoft.Web/sites", 120 | "apiVersion": "2015-08-01", 121 | "location": "[variables('resourcesLocation')]", 122 | "kind": "app", 123 | "dependsOn": [ 124 | "[resourceId('Microsoft.Web/serverfarms/', variables('appServicePlanName'))]" 125 | ], 126 | "name": "[variables('webAppName')]", 127 | "properties": { 128 | "name": "[variables('webAppName')]", 129 | "serverFarmId": "[variables('appServicePlanName')]", 130 | "siteConfig": { 131 | "appSettings": [ 132 | { 133 | "name": "WEBSITE_NODE_DEFAULT_VERSION", 134 | "value": "10.14.1" 135 | }, 136 | { 137 | "name": "MicrosoftAppId", 138 | "value": "[parameters('appId')]" 139 | }, 140 | { 141 | "name": "MicrosoftAppPassword", 142 | "value": "[parameters('appSecret')]" 143 | } 144 | ], 145 | "cors": { 146 | "allowedOrigins": [ 147 | "https://botservice.hosting.portal.azure.net", 148 | "https://hosting.onecloud.azure-test.net/" 149 | ] 150 | } 151 | } 152 | } 153 | }, 154 | { 155 | "apiVersion": "2017-12-01", 156 | "type": "Microsoft.BotService/botServices", 157 | "name": "[parameters('botId')]", 158 | "location": "global", 159 | "kind": "bot", 160 | "sku": { 161 | "name": "[parameters('botSku')]" 162 | }, 163 | "properties": { 164 | "name": "[parameters('botId')]", 165 | "displayName": "[parameters('botId')]", 166 | "endpoint": "[variables('botEndpoint')]", 167 | "msaAppId": "[parameters('appId')]", 168 | "developerAppInsightsApplicationId": null, 169 | "developerAppInsightKey": null, 170 | "publishingCredentials": null, 171 | "storageResourceId": null 172 | }, 173 | "dependsOn": [ 174 | "[resourceId('Microsoft.Web/sites/', variables('webAppName'))]" 175 | ] 176 | } 177 | ], 178 | "outputs": {} 179 | } 180 | } 181 | } 182 | ] 183 | } -------------------------------------------------------------------------------- /GPTVirtualAssistant/scripts/DeploymentTemplates/template-with-preexisting-rg.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", 3 | "contentVersion": "1.0.0.0", 4 | "parameters": { 5 | "name": { 6 | "type": "string" 7 | }, 8 | "appId": { 9 | "type": "string", 10 | "metadata": { 11 | "description": "Active Directory App ID, set as MicrosoftAppId in the Web App's Application Settings." 12 | } 13 | }, 14 | "appSecret": { 15 | "type": "string", 16 | "metadata": { 17 | "description": "Active Directory App Password, set as MicrosoftAppPassword in the Web App's Application Settings. Defaults to \"\"." 18 | } 19 | }, 20 | "useCosmosDb": { 21 | "type": "bool", 22 | "defaultValue": true 23 | }, 24 | "useAppInsights": { 25 | "type": "bool", 26 | "defaultValue": true 27 | }, 28 | "shouldCreateAuthoringResource": { 29 | "type": "bool", 30 | "defaultValue": true 31 | }, 32 | "shouldCreateLuisResource": { 33 | "type": "bool", 34 | "defaultValue": true 35 | }, 36 | "cosmosDbName": { 37 | "type": "string", 38 | "defaultValue": "[parameters('name')]" 39 | }, 40 | "botId": { 41 | "type": "string", 42 | "metadata": { 43 | "description": "The globally unique and immutable bot ID. Also used to configure the displayName of the bot, which is mutable." 44 | } 45 | }, 46 | "botSku": { 47 | "defaultValue": "F0", 48 | "type": "string", 49 | "metadata": { 50 | "description": "The pricing tier of the Bot Service Registration. Acceptable values are F0 and S1." 51 | } 52 | }, 53 | "luisAuthoringKey": { 54 | "type": "string", 55 | "defaultValue": "" 56 | }, 57 | "newAppServicePlanName": { 58 | "type": "string", 59 | "defaultValue": "[parameters('name')]", 60 | "metadata": { 61 | "description": "The name of the new App Service Plan." 62 | } 63 | }, 64 | "newAppServicePlanSku": { 65 | "type": "object", 66 | "defaultValue": { 67 | "name": "S1", 68 | "tier": "Standard", 69 | "size": "S1", 70 | "family": "S", 71 | "capacity": 1 72 | }, 73 | "metadata": { 74 | "description": "The SKU of the App Service Plan. Defaults to Standard values." 75 | } 76 | }, 77 | "appServicePlanLocation": { 78 | "type": "string", 79 | "metadata": { 80 | "description": "The location of the App Service Plan." 81 | } 82 | }, 83 | "existingAppServicePlan": { 84 | "type": "string", 85 | "defaultValue": "", 86 | "metadata": { 87 | "description": "Name of the existing App Service Plan used to create the Web App for the bot." 88 | } 89 | }, 90 | "newWebAppName": { 91 | "type": "string", 92 | "defaultValue": "[parameters('name')]", 93 | "metadata": { 94 | "description": "The globally unique name of the Web App. Defaults to the value passed in for \"botId\"." 95 | } 96 | }, 97 | "appInsightsName": { 98 | "type": "string", 99 | "defaultValue": "[parameters('name')]" 100 | }, 101 | "location": { 102 | "type": "string", 103 | "defaultValue": "[resourceGroup().location]" 104 | }, 105 | "appInsightsLocation": { 106 | "type": "string", 107 | "defaultValue": "[resourceGroup().location]" 108 | }, 109 | "useStorage": { 110 | "type": "bool", 111 | "defaultValue": true 112 | }, 113 | "storageAccountName": { 114 | "type": "string", 115 | "defaultValue": "[parameters('name')]" 116 | }, 117 | "luisServiceName": { 118 | "type": "string", 119 | "defaultValue": "[concat(parameters('name'), '-luis')]" 120 | }, 121 | "luisServiceAuthoringSku": { 122 | "type": "string", 123 | "defaultValue": "F0" 124 | }, 125 | "luisServiceRunTimeSku": { 126 | "type": "string", 127 | "defaultValue": "S0" 128 | }, 129 | "luisServiceLocation": { 130 | "type": "string", 131 | "defaultValue": "[resourceGroup().location]" 132 | } 133 | }, 134 | "variables": { 135 | "defaultAppServicePlanName": "[if(empty(parameters('existingAppServicePlan')), 'createNewAppServicePlan', parameters('existingAppServicePlan'))]", 136 | "useExistingAppServicePlan": "[not(equals(variables('defaultAppServicePlanName'), 'createNewAppServicePlan'))]", 137 | "servicePlanName": "[if(variables('useExistingAppServicePlan'), parameters('existingAppServicePlan'), parameters('newAppServicePlanName'))]", 138 | "resourcesLocation": "[parameters('appServicePlanLocation')]", 139 | "cosmosDbAccountName": "[toLower(take(replace(parameters('cosmosDbName'), '_', ''), 31))]", 140 | "webAppName": "[if(empty(parameters('newWebAppName')), parameters('botId'), parameters('newWebAppName'))]", 141 | "siteHost": "[concat(variables('webAppName'), '.azurewebsites.net')]", 142 | "botEndpoint": "[concat('https://', variables('siteHost'), '/api/messages')]", 143 | "storageAccountName": "[toLower(take(replace(replace(parameters('storageAccountName'), '-', ''), '_', ''), 24))]", 144 | "LuisAuthoringAccountName": "[concat(parameters('luisServiceName'), '-authoring')]" 145 | }, 146 | "resources": [ 147 | { 148 | "apiVersion": "2018-02-01", 149 | "name": "1d41002f-62a1-49f3-bd43-2f3f32a19cbb", 150 | "type": "Microsoft.Resources/deployments", 151 | "properties": { 152 | "mode": "Incremental", 153 | "template": { 154 | "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", 155 | "contentVersion": "1.0.0.0", 156 | "resources": [] 157 | } 158 | } 159 | }, 160 | { 161 | "comments": "Create a new App Service Plan if no existing App Service Plan name was passed in.", 162 | "type": "Microsoft.Web/serverfarms", 163 | "condition": "[not(variables('useExistingAppServicePlan'))]", 164 | "name": "[variables('servicePlanName')]", 165 | "apiVersion": "2018-02-01", 166 | "location": "[variables('resourcesLocation')]", 167 | "sku": "[parameters('newAppServicePlanSku')]", 168 | "properties": { 169 | "name": "[variables('servicePlanName')]" 170 | } 171 | }, 172 | { 173 | "comments": "Create a Web App using an App Service Plan", 174 | "type": "Microsoft.Web/sites", 175 | "apiVersion": "2015-08-01", 176 | "location": "[variables('resourcesLocation')]", 177 | "kind": "app", 178 | "dependsOn": ["[resourceId('Microsoft.Web/serverfarms/', variables('servicePlanName'))]"], 179 | "name": "[variables('webAppName')]", 180 | "properties": { 181 | "name": "[variables('webAppName')]", 182 | "serverFarmId": "[variables('servicePlanName')]", 183 | "siteConfig": { 184 | "webSocketsEnabled": true, 185 | "appSettings": [ 186 | { 187 | "name": "WEBSITE_NODE_DEFAULT_VERSION", 188 | "value": "10.14.1" 189 | }, 190 | { 191 | "name": "MicrosoftAppId", 192 | "value": "[parameters('appId')]" 193 | }, 194 | { 195 | "name": "MicrosoftAppPassword", 196 | "value": "[parameters('appSecret')]" 197 | } 198 | ], 199 | "cors": { 200 | "allowedOrigins": [ 201 | "https://botservice.hosting.portal.azure.net", 202 | "https://hosting.onecloud.azure-test.net/" 203 | ] 204 | } 205 | } 206 | } 207 | }, 208 | { 209 | "comments": "CosmosDB for bot state.", 210 | "type": "Microsoft.DocumentDB/databaseAccounts", 211 | "kind": "GlobalDocumentDB", 212 | "apiVersion": "2015-04-08", 213 | "name": "[variables('cosmosDbAccountName')]", 214 | "location": "[parameters('location')]", 215 | "properties": { 216 | "databaseAccountOfferType": "Standard", 217 | "locations": [ 218 | { 219 | "locationName": "[parameters('location')]", 220 | "failoverPriority": 0 221 | } 222 | ] 223 | }, 224 | "condition": "[parameters('useCosmosDb')]" 225 | }, 226 | { 227 | "type": "Microsoft.DocumentDB/databaseAccounts/sqlDatabases", 228 | "apiVersion": "2020-03-01", 229 | "name": "[concat(variables('cosmosDbAccountName'), '/botstate-db')]", 230 | "dependsOn": ["[resourceId('Microsoft.DocumentDB/databaseAccounts', variables('cosmosDbAccountName'))]"], 231 | "properties": { 232 | "resource": { 233 | "id": "botstate-db" 234 | }, 235 | "options": {} 236 | }, 237 | "condition": "[parameters('useCosmosDb')]" 238 | }, 239 | { 240 | "type": "Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers", 241 | "apiVersion": "2020-03-01", 242 | "name": "[concat(variables('cosmosDbAccountName'), '/botstate-db/botstate-container')]", 243 | "dependsOn": [ 244 | "[resourceId('Microsoft.DocumentDB/databaseAccounts/sqlDatabases', variables('cosmosDbAccountName'), 'botstate-db')]", 245 | "[resourceId('Microsoft.DocumentDB/databaseAccounts', variables('cosmosDbAccountName'))]" 246 | ], 247 | "properties": { 248 | "resource": { 249 | "id": "botstate-container", 250 | "indexingPolicy": { 251 | "indexingMode": "consistent", 252 | "automatic": true, 253 | "includedPaths": [ 254 | { 255 | "path": "/*" 256 | } 257 | ], 258 | "excludedPaths": [ 259 | { 260 | "path": "/\"_etag\"/?" 261 | } 262 | ] 263 | }, 264 | "partitionKey": { 265 | "paths": ["/id"], 266 | "kind": "Hash" 267 | }, 268 | "conflictResolutionPolicy": { 269 | "mode": "LastWriterWins", 270 | "conflictResolutionPath": "/_ts" 271 | } 272 | }, 273 | "options": {} 274 | }, 275 | "condition": "[parameters('useCosmosDb')]" 276 | }, 277 | { 278 | "apiVersion": "2018-07-12", 279 | "type": "Microsoft.BotService/botServices", 280 | "name": "[parameters('botId')]", 281 | "location": "global", 282 | "kind": "azurebot", 283 | "sku": { 284 | "name": "[parameters('botSku')]" 285 | }, 286 | "properties": { 287 | "name": "[parameters('botId')]", 288 | "displayName": "[parameters('botId')]", 289 | "endpoint": "[variables('botEndpoint')]", 290 | "msaAppId": "[parameters('appId')]", 291 | "openWithHint": "bfcomposer://", 292 | "developerAppInsightsApplicationId": null, 293 | "developerAppInsightKey": null, 294 | "publishingCredentials": null, 295 | "storageResourceId": null 296 | }, 297 | "dependsOn": ["[resourceId('Microsoft.Web/sites/', variables('webAppName'))]"] 298 | }, 299 | { 300 | "comments": "app insights", 301 | "type": "Microsoft.Insights/components", 302 | "kind": "web", 303 | "apiVersion": "2015-05-01", 304 | "name": "[parameters('appInsightsName')]", 305 | "location": "[parameters('appInsightsLocation')]", 306 | "properties": { 307 | "Application_Type": "web" 308 | }, 309 | "condition": "[parameters('useAppInsights')]" 310 | }, 311 | { 312 | "comments": "storage account", 313 | "type": "Microsoft.Storage/storageAccounts", 314 | "kind": "StorageV2", 315 | "apiVersion": "2018-07-01", 316 | "name": "[variables('storageAccountName')]", 317 | "location": "[parameters('location')]", 318 | "sku": { 319 | "name": "Standard_LRS" 320 | }, 321 | "condition": "[parameters('useStorage')]" 322 | }, 323 | { 324 | "comments": "Cognitive service authoring key for all LUIS apps.", 325 | "apiVersion": "2017-04-18", 326 | "name": "[variables('LuisAuthoringAccountName')]", 327 | "location": "[parameters('luisServiceLocation')]", 328 | "type": "Microsoft.CognitiveServices/accounts", 329 | "kind": "LUIS.Authoring", 330 | "sku": { 331 | "name": "[parameters('luisServiceAuthoringSku')]" 332 | }, 333 | "condition": "[parameters('shouldCreateAuthoringResource')]" 334 | }, 335 | { 336 | "comments": "Cognitive service endpoint key for all LUIS apps.", 337 | "type": "Microsoft.CognitiveServices/accounts", 338 | "kind": "LUIS", 339 | "apiVersion": "2017-04-18", 340 | "name": "[parameters('luisServiceName')]", 341 | "location": "[parameters('luisServiceLocation')]", 342 | "sku": { 343 | "name": "[parameters('luisServiceRunTimeSku')]" 344 | }, 345 | "condition": "[parameters('shouldCreateLuisResource')]" 346 | } 347 | ], 348 | "outputs": { 349 | "ApplicationInsights": { 350 | "type": "object", 351 | "value": { 352 | "InstrumentationKey": "[if(parameters('useAppInsights'), reference(resourceId('Microsoft.Insights/components', parameters('appInsightsName'))).InstrumentationKey, '')]" 353 | } 354 | }, 355 | "cosmosDb": { 356 | "type": "object", 357 | "value": { 358 | "cosmosDBEndpoint": "[if(parameters('useCosmosDb'), reference(resourceId('Microsoft.DocumentDB/databaseAccounts', variables('cosmosDbAccountName'))).documentEndpoint, '')]", 359 | "authKey": "[if(parameters('useCosmosDb'), listKeys(resourceId('Microsoft.DocumentDB/databaseAccounts', variables('cosmosDbAccountName')), '2015-04-08').primaryMasterKey, '')]", 360 | "databaseId": "botstate-db", 361 | "containerId": "botstate-container" 362 | } 363 | }, 364 | "blobStorage": { 365 | "type": "object", 366 | "value": { 367 | "connectionString": "[if(parameters('useStorage'), concat('DefaultEndpointsProtocol=https;AccountName=', variables('storageAccountName'), ';AccountKey=', listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName')), '2018-07-01').keys[0].value, ';EndpointSuffix=core.windows.net'), '')]", 368 | "container": "transcripts" 369 | } 370 | }, 371 | "luis": { 372 | "type": "object", 373 | "value": { 374 | "endpointKey": "[if(parameters('shouldCreateLuisResource'), listKeys(resourceId('Microsoft.CognitiveServices/accounts', parameters('luisServiceName')),'2017-04-18').key1, '')]", 375 | "authoringKey": "[if(parameters('shouldCreateAuthoringResource'), listKeys(resourceId('Microsoft.CognitiveServices/accounts', variables('LuisAuthoringAccountName')),'2017-04-18').key1, parameters('luisAuthoringKey'))]", 376 | "region": "[parameters('luisServiceLocation')]", 377 | "endpoint": "[if(parameters('shouldCreateLuisResource'), reference(resourceId('Microsoft.CognitiveServices/accounts', parameters('luisServiceName'))).endpoint, '')]", 378 | "authoringEndpoint": "[if(parameters('shouldCreateAuthoringResource'), reference(resourceId('Microsoft.CognitiveServices/accounts', variables('LuisAuthoringAccountName'))).endpoint, '')]" 379 | } 380 | } 381 | } 382 | } 383 | -------------------------------------------------------------------------------- /GPTVirtualAssistant/scripts/README.md: -------------------------------------------------------------------------------- 1 | # Manually provision resources and publish a bot to Azure (_Preview_) 2 | 3 | This article covers script-based instructions to manually provision resources and publish a bot built using Composer to _Azure Web App (Preview)_ and _Azure Functions (Preview)_. 4 | 5 | ## Prerequisites 6 | 7 | - A subscription to [Microsoft Azure](https://azure.microsoft.com/free/). 8 | - [A basic bot built using Composer](https://aka.ms/composer-create-first-bot). 9 | - Latest version of the [Azure CLI](https://docs.microsoft.com/cli/azure/install-azure-cli). 10 | - [Node.js](https://nodejs.org/). Use version 12.13.0 or later. 11 | - PowerShell version 6.0 and later. 12 | 13 | ## Provision Azure resources 14 | 15 | This section covers steps to provision required Azure resources using JavaScript scripts. If you already have your Azure resources provisioned, skip to the [publish a bot to Azure](#publish-a-bot-to-azure) section. 16 | 17 | Follow these instructions to manually provision Azure resources: 18 | 19 | 1. Open a new Command Prompt and navigate to the **scripts** folder of your bot's project folder. For example: 20 | 21 | ```cmd 22 | cd C:\Users\UserName\Documents\Composer\BotName\scripts 23 | ``` 24 | 25 | 2. Run the following command to install the dependencies: 26 | 27 | ```cmd 28 | npm install 29 | ``` 30 | 31 | 3. Run the following command to provision new Azure resources. 32 | 33 | - **_Azure Web App (Preview)_**: 34 | 35 | ```cmd 36 | node provisionComposer.js --subscriptionId= --name= --appPassword= --environment= 37 | ``` 38 | 39 | - **_Azure Functions (Preview)_**: 40 | 41 | ```cmd 42 | node provisionComposer.js --subscriptionId= --name= --appPassword= --environment= --customArmTemplate=DeploymentTemplates/function-template-with-preexisting-rg.json 43 | ``` 44 | 45 | | Property | Description | 46 | | --------------------------- | --------------------------------------------------------------------------------------- | 47 | | Your Azure Subscription ID | Find it in your Azure resource in the **Subscription ID** field. | 48 | | Name of your resource group | The name you give to the resource group you are creating. | 49 | | App password | At least 16 characters with at least one number, one letter, and one special character. | 50 | | Name for environment | The name you give to the publish environment. | 51 | 52 | Once completed, the provision scripts will create the following resources in the Azure portal: 53 | 54 | | Resource | Required/Optional | 55 | | --------------------------------------------- | ----------------- | 56 | | App Service plan | Required | 57 | | App Service | Required | 58 | | Application Registration | Required | 59 | | Azure Cosmos DB | Optional | 60 | | Application Insights | Optional | 61 | | Azure Blob Storage | Optional | 62 | | LUIS authoring resource (Cognitive Services) | Optional | 63 | | LUIS prediction resource (Cognitive Services) | Optional | 64 | | QnA Maker resources (Cognitive Services) | Optional | 65 | 66 | > [!TIP] 67 | > Read the [parameters list](#provision-scripts-parameters-list) to customize the provision scripts and create the Azure resources you want. 68 | 69 | 1. You will be asked to login to the Azure portal in your browser. 70 | 71 | > ![publish az login](./media/publish-az-login.png) 72 | 73 | 2. If you see the error message "InsufficientQuota", add a param '--createLuisAuthoringResource false' and run the script again. 74 | 75 | - **_Azure Web App_**: 76 | 77 | ```cmd 78 | node provisionComposer.js --subscriptionId= --name=--appPassword= --environment= --createLuisAuthoringResource false 79 | ``` 80 | 81 | - **_Azure Functions_**: 82 | 83 | ```cmd 84 | node provisionComposer.js --subscriptionId= --name= --appPassword= --environment= --createLuisAuthoringResource false --customArmTemplate=DeploymentTemplates/function-template-with-preexisting-rg.json 85 | ``` 86 | 87 | > [!NOTE] 88 | > If you use `--createLuisAuthoringResource false` in this step, you should manually add the LUIS authoring key to the publish configuration in the [deploy bot to new Azure resources](#deploy-bot-to-new-azure-resources) section. The default region is `westus`. To provision to other regions, you should add `--location region`. 89 | 90 | 4. As the Azure resources are being provisioned, which takes a few minutes, you will see the following: 91 | 92 | > ![Create Azure resource command line](./media/create-azure-resource-command-line.png) 93 | 94 | Once completed, you will see the generated JSON appears in the command line like the following. The JSON output is the publishing profile, which will be used in step **3** of the [Publish a bot to Azure](#publish-a-bot-to-azure) section. 95 | 96 | ```json 97 | { 98 | "accessToken": "", 99 | "name": "", 100 | "environment": "", 101 | "hostname": "", 102 | "luisResource": "", 103 | "settings": { 104 | "applicationInsights": { 105 | "InstrumentationKey": "" 106 | }, 107 | "cosmosDb": { 108 | "cosmosDBEndpoint": "", 109 | "authKey": "", 110 | "databaseId": "botstate-db", 111 | "collectionId": "botstate-collection", 112 | "containerId": "botstate-container" 113 | }, 114 | "blobStorage": { 115 | "connectionString": "", 116 | "container": "transcripts" 117 | }, 118 | "luis": { 119 | "endpointKey": "", 120 | "authoringKey": "", 121 | "region": "westus" 122 | }, 123 | "qna": { 124 | "endpoint": "", 125 | "subscriptionKey": "" 126 | }, 127 | "MicrosoftAppId": "", 128 | "MicrosoftAppPassword": "" 129 | } 130 | } 131 | ``` 132 | 133 | ## Publish a bot to Azure 134 | 135 | This section covers instructions to publish a bot to Azure using PowerShell scripts. Make sure you already have required Azure resources provisioned before publishing a bot, if not, follow these instructions from the [provision Azure resources](#provision-azure-resources) section. 136 | 137 | Follow these steps to manually publish a bot to Azure: 138 | 139 | 1. Install the required dependencies. 140 | 141 | bf command 142 | 143 | ```cmd 144 | npm i -g @microsoft/botframework-cli@next 145 | ``` 146 | 147 | bf plugins 148 | 149 | ```cmd 150 | bf plugins:install @microsoft/bf-sampler-cli@beta 151 | ``` 152 | 153 | 2. [Eject your bot's C# runtime](https://aka.ms/composer-customize-action#export-runtime). 154 | 155 | 3. Save your publishing profile in `json` format (the JSON output from step **4** of the [provision Azure resources](#provision-azure-resources) section and execute the following command: 156 | 157 | ```powershell 158 | .\Scripts\deploy.ps1 -publishProfilePath 159 | ``` 160 | 161 | > [!NOTE] 162 | > Make sure you [set the correct subscription](https://docs.microsoft.com/cli/azure/account?view=azure-cli-latest#az_account_set) when running the scripts to publish your bot. Use the Azure CLI command `az account set --subscription` to set subscription if needed. The publishing process will take a couple of minutes to finish. 163 | 164 | ## Refresh your Azure Token 165 | 166 | Follow these steps to get a new token if you encounter an error about your access token being expired: 167 | 168 | - Open a terminal window. 169 | - Run `az account get-access-token`. 170 | - This will result in a JSON object containing the new `accessToken`, printed to the console. 171 | - Copy the value of the accessToken from the terminal and into the publish `accessToken` field in the profile in Composer. 172 | 173 | ## Additional information 174 | 175 | ### Provision scripts parameters list 176 | 177 | You don't need to create a complete list of the Azure resources as covered in **step 3** of the [provision Azure resources](#provision-azure-resources) section. The following is a table of the parameters you can use to customize the provision scripts so that you only provision the resources needed. 178 | 179 | | Parameter | Required/Optional | Default value | Description | 180 | | --------------------------- | ----------------- | -------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | 181 | | subscriptionId | Required | N/A | Your Azure subscription ID. | 182 | | name | Required | N/A | The name of your resource group | 183 | | appPassword | Required | N/A | The password to create the resource. It must be at least 16 characters long, contain at least 1 upper or lower case alphabetical character, and contain at least 1 special character | 184 | | environment | Optional | dev | N/A | 185 | | location | Optional | `westus` | Your Azure resource group region | 186 | | tenantId | Optional | default tenantId | ID of your tenant if required. | 187 | | customArmTemplate | Optional | `/DeploymentTemplates/template-with-preexisting-rg.json` | For Azure Functions or your own template for a custom deployment. | 188 | | createLuisResource | Optional | `true` | The LUIS prediction resource to create. Region is default to `westus` and cannot be changed. | 189 | | createLuisAuthoringResource | Optional | true | The LUIS authoring resource to create. Region is default to `westus` and cannot be changed. | 190 | | createQnAResource | Optional | `true` | The QnA resource to create. | 191 | | createCosmosDb | Optional | `true` | The CosmosDb resource to create. | 192 | | createStorage | Optional | `true` | The BlobStorage resource to create. | 193 | | createAppInsights | Optional | `true` | The AppInsights resource to create. | 194 | -------------------------------------------------------------------------------- /GPTVirtualAssistant/scripts/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "azure_provision", 3 | "version": "1.0.0", 4 | "description": "provision to azure cloud", 5 | "main": "provisionComposer.js", 6 | "license": "MIT", 7 | "scripts": { 8 | "start": "node provisionComposer.js" 9 | }, 10 | "dependencies": { 11 | "@azure/arm-appinsights": "^2.1.0", 12 | "@azure/arm-botservice": "^3.1.0", 13 | "@azure/arm-resources": "^2.1.0", 14 | "@azure/graph": "^5.0.1", 15 | "@azure/ms-rest-nodeauth": "^3.0.3", 16 | "@types/fs-extra": "^8.1.0", 17 | "chalk": "^4.0.0", 18 | "fs-extra": "^8.1.0", 19 | "minimist": "^1.2.5", 20 | "ora": "^4.0.4", 21 | "request-promise": "^4.2.5" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /GPTVirtualAssistant/scripts/provisionComposer.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | const chalk = require('chalk'); 4 | const fs = require('fs-extra'); 5 | const msRestNodeAuth = require('@azure/ms-rest-nodeauth'); 6 | const argv = require('minimist')(process.argv.slice(2)); 7 | const path = require('path'); 8 | const rp = require('request-promise'); 9 | const { promisify } = require('util'); 10 | const { GraphRbacManagementClient } = require('@azure/graph'); 11 | const { ApplicationInsightsManagementClient } = require('@azure/arm-appinsights'); 12 | const { AzureBotService } = require('@azure/arm-botservice'); 13 | const { ResourceManagementClient } = require('@azure/arm-resources'); 14 | const readFile = promisify(fs.readFile); 15 | const ora = require('ora'); 16 | 17 | const logger = (msg) => { 18 | if (msg.status === BotProjectDeployLoggerType.PROVISION_ERROR) { 19 | console.log(chalk.red(msg.message)); 20 | } else if (msg.status === BotProjectDeployLoggerType.PROVISION_ERROR_DETAILS) { 21 | console.log(chalk.white(msg.message)); 22 | } else { 23 | console.log(chalk.green(msg.message)); 24 | } 25 | }; 26 | 27 | const usage = () => { 28 | const options = [ 29 | ['subscriptionId', 'Azure Subscription Id'], 30 | ['name', 'Project Name'], 31 | ['appPassword', '16 character password'], 32 | ['environment', 'Environment name (Defaults to dev)'], 33 | ['location', 'Azure Region (Defaults to westus)'], 34 | ['resourceGroup', 'Name of your resource group (Defaults to name-environment)'], 35 | ['appId', 'Microsoft App ID (Will create if absent)'], 36 | ['tenantId', 'ID of your tenant if required (will choose first in list by default)'], 37 | ['createLuisResource', 'Create a LUIS resource? Default true'], 38 | ['createLuisAuthoringResource', 'Create a LUIS authoring resource? Default true'], 39 | ['createCosmosDb', 'Create a CosmosDB? Default true'], 40 | ['createStorage', 'Create a storage account? Default true'], 41 | ['createAppInsights', 'Create an AppInsights resource? Default true'], 42 | ['createQnAResource', 'Create a QnA resource? Default true'], 43 | [ 44 | 'customArmTemplate', 45 | 'Path to runtime ARM template. By default it will use an Azure WebApp template. Pass `DeploymentTemplates/function-template-with-preexisting-rg.json` for Azure Functions or your own template for a custom deployment.', 46 | ], 47 | ['qnaTemplate', 'Path to qna template. By default it will use `DeploymentTemplates/qna-template.json`'], 48 | ]; 49 | 50 | const instructions = [ 51 | ``, 52 | chalk.bold('Provision Azure resources for use with Bot Framework Composer bots'), 53 | `* This script will create a new resource group and the necessary Azure resources needed to operate a Bot Framework bot in the cloud.`, 54 | `* Use this to create a publishing profile used in Composer's "Publish" toolbar.`, 55 | ``, 56 | chalk.bold(`Basic Usage:`), 57 | chalk.greenBright(`node provisionComposer --subscriptionId=`) + 58 | chalk.yellow('') + 59 | chalk.greenBright(' --name=') + 60 | chalk.yellow('') + 61 | chalk.greenBright(' --appPassword=') + 62 | chalk.yellow('<16 character password>'), 63 | ``, 64 | chalk.bold(`All options:`), 65 | ...options.map((option) => { 66 | return chalk.greenBright('--' + option[0]) + '\t' + chalk.yellow(option[1]); 67 | }), 68 | ]; 69 | 70 | console.log(instructions.join('\n')); 71 | }; 72 | 73 | // check for required parameters 74 | if (Object.keys(argv).length === 0) { 75 | return usage(); 76 | } 77 | 78 | if (!argv.name || !argv.subscriptionId || !argv.appPassword) { 79 | return usage(); 80 | } 81 | 82 | // Get required fields from the arguments 83 | const subId = argv.subscriptionId; 84 | const name = argv.name.toString(); 85 | const appPassword = argv.appPassword; 86 | 87 | // Get optional fields from the arguments 88 | const environment = argv.environment || 'dev'; 89 | const location = argv.location || 'westus'; 90 | const appId = argv.appId; // MicrosoftAppId - generated if left blank 91 | 92 | // Get option flags 93 | const createLuisResource = argv.createLuisResource == 'false' ? false : true; 94 | const createLuisAuthoringResource = argv.createLuisAuthoringResource == 'false' ? false : true; 95 | const createCosmosDb = argv.createCosmosDb == 'false' ? false : true; 96 | const createStorage = argv.createStorage == 'false' ? false : true; 97 | const createAppInsights = argv.createAppInsights == 'false' ? false : true; 98 | const createQnAResource = argv.createQnAResource == 'false' ? false : true; 99 | var tenantId = argv.tenantId ? argv.tenantId : ''; 100 | 101 | const templatePath = 102 | argv.customArmTemplate || path.join(__dirname, 'DeploymentTemplates', 'template-with-preexisting-rg.json'); 103 | const qnaTemplatePath = argv.qnaTemplate || path.join(__dirname, 'DeploymentTemplates', 'qna-template.json'); 104 | const resourceGroup = argv.resourceGroup || `${name}-${environment}`; 105 | 106 | const BotProjectDeployLoggerType = { 107 | // Logger Type for Provision 108 | PROVISION_INFO: 'PROVISION_INFO', 109 | PROVISION_ERROR: 'PROVISION_ERROR', 110 | PROVISION_WARNING: 'PROVISION_WARNING', 111 | PROVISION_SUCCESS: 'PROVISION_SUCCESS', 112 | PROVISION_ERROR_DETAILS: 'PROVISION_ERROR_DETAILS', 113 | }; 114 | 115 | /** 116 | * Create a Bot Framework registration 117 | * @param {} graphClient 118 | * @param {*} displayName 119 | * @param {*} appPassword 120 | */ 121 | const createApp = async (graphClient, displayName, appPassword) => { 122 | try { 123 | const createRes = await graphClient.applications.create({ 124 | displayName: displayName, 125 | passwordCredentials: [ 126 | { 127 | value: appPassword, 128 | startDate: new Date(), 129 | endDate: new Date(new Date().setFullYear(new Date().getFullYear() + 2)), 130 | }, 131 | ], 132 | availableToOtherTenants: true, 133 | replyUrls: ['https://token.botframework.com/.auth/web/redirect'], 134 | }); 135 | return createRes; 136 | } catch (err) { 137 | logger({ 138 | status: BotProjectDeployLoggerType.PROVISION_ERROR, 139 | message: err.body.message, 140 | }); 141 | return false; 142 | } 143 | }; 144 | 145 | /** 146 | * Create an Azure resources group 147 | * @param {} client 148 | * @param {*} location 149 | * @param {*} resourceGroupName 150 | */ 151 | const createResourceGroup = async (client, location, resourceGroupName) => { 152 | logger({ 153 | status: BotProjectDeployLoggerType.PROVISION_INFO, 154 | message: `> Creating resource group ...`, 155 | }); 156 | const param = { 157 | location: location, 158 | }; 159 | 160 | return await client.resourceGroups.createOrUpdate(resourceGroupName, param); 161 | }; 162 | 163 | /** 164 | * Format parameters 165 | * @param {} scope 166 | */ 167 | const pack = (scope) => { 168 | return { 169 | value: scope, 170 | }; 171 | }; 172 | 173 | const unpackObject = (output) => { 174 | const unpacked = {}; 175 | for (const key in output) { 176 | const objValue = output[key]; 177 | if (objValue.value) { 178 | unpacked[key] = objValue.value; 179 | } 180 | } 181 | return unpacked; 182 | }; 183 | 184 | /** 185 | * For more information about this api, please refer to this doc: https://docs.microsoft.com/en-us/rest/api/resources/Tenants/List 186 | * @param {*} accessToken 187 | */ 188 | const getTenantId = async (accessToken) => { 189 | if (!accessToken) { 190 | throw new Error( 191 | 'Error: Missing access token. Please provide a non-expired Azure access token. Tokens can be obtained by running az account get-access-token' 192 | ); 193 | } 194 | if (!subId) { 195 | throw new Error(`Error: Missing subscription Id. Please provide a valid Azure subscription id.`); 196 | } 197 | try { 198 | const tenantUrl = `https://management.azure.com/subscriptions/${subId}?api-version=2020-01-01`; 199 | const options = { 200 | headers: { Authorization: `Bearer ${accessToken}` }, 201 | }; 202 | const response = await rp.get(tenantUrl, options); 203 | const jsonRes = JSON.parse(response); 204 | if (jsonRes.tenantId === undefined) { 205 | throw new Error(`No tenants found in the account.`); 206 | } 207 | return jsonRes.tenantId; 208 | } catch (err) { 209 | throw new Error(`Get Tenant Id Failed, details: ${getErrorMesssage(err)}`); 210 | } 211 | }; 212 | 213 | /** 214 | * @param {*} appId the appId of application registration 215 | * @param {*} appPwd the app password of application registration 216 | * @param {*} location the locaiton of all resources 217 | * @param {*} name the base name of resources 218 | * @param {*} shouldCreateAuthoringResource 219 | * @param {*} shouldCreateLuisResource 220 | * @param {*} useAppInsights 221 | * @param {*} useCosmosDb 222 | * @param {*} useStorage 223 | */ 224 | const getDeploymentTemplateParam = ( 225 | appId, 226 | appPwd, 227 | location, 228 | name, 229 | shouldCreateAuthoringResource, 230 | shouldCreateLuisResource, 231 | useAppInsights, 232 | useCosmosDb, 233 | useStorage 234 | ) => { 235 | return { 236 | appId: pack(appId), 237 | appSecret: pack(appPwd), 238 | name: pack(name), 239 | appServicePlanLocation: pack(location), 240 | botId: pack(name), 241 | shouldCreateAuthoringResource: pack(shouldCreateAuthoringResource), 242 | shouldCreateLuisResource: pack(shouldCreateLuisResource), 243 | useAppInsights: pack(useAppInsights), 244 | useCosmosDb: pack(useCosmosDb), 245 | useStorage: pack(useStorage), 246 | }; 247 | }; 248 | 249 | /** 250 | * Get QnA template param 251 | */ 252 | const getQnaTemplateParam = (location, name) => { 253 | return { 254 | appServicePlanLocation: pack(location), 255 | name: pack(name), 256 | }; 257 | }; 258 | 259 | /** 260 | * Validate the qna template and the qna template param 261 | */ 262 | const validateQnADeployment = async (client, resourceGroupName, deployName, templateParam) => { 263 | logger({ 264 | status: BotProjectDeployLoggerType.PROVISION_INFO, 265 | message: '> Validating QnA deployment ...', 266 | }); 267 | 268 | const templateFile = await readFile(qnaTemplatePath, { encoding: 'utf-8' }); 269 | const deployParam = { 270 | properties: { 271 | template: JSON.parse(templateFile), 272 | parameters: templateParam, 273 | mode: 'Incremental', 274 | }, 275 | }; 276 | return await client.deployments.validate(resourceGroupName, deployName, deployParam); 277 | }; 278 | 279 | /** 280 | * Create a QnA resource deployment 281 | * @param {*} client 282 | * @param {*} resourceGroupName 283 | * @param {*} deployName 284 | * @param {*} templateParam 285 | */ 286 | const createQnADeployment = async (client, resourceGroupName, deployName, templateParam) => { 287 | const templateFile = await readFile(qnaTemplatePath, { encoding: 'utf-8' }); 288 | const deployParam = { 289 | properties: { 290 | template: JSON.parse(templateFile), 291 | parameters: templateParam, 292 | mode: 'Incremental', 293 | }, 294 | }; 295 | 296 | return await client.deployments.createOrUpdate(resourceGroupName, deployName, deployParam); 297 | }; 298 | 299 | /** 300 | * Validate the deployment using the Azure API 301 | */ 302 | const validateDeployment = async (client, resourceGroupName, deployName, templateParam) => { 303 | logger({ 304 | status: BotProjectDeployLoggerType.PROVISION_INFO, 305 | message: '> Validating Azure deployment ...', 306 | }); 307 | 308 | const templateFile = await readFile(templatePath, { encoding: 'utf-8' }); 309 | const deployParam = { 310 | properties: { 311 | template: JSON.parse(templateFile), 312 | parameters: templateParam, 313 | mode: 'Incremental', 314 | }, 315 | }; 316 | return await client.deployments.validate(resourceGroupName, deployName, deployParam); 317 | }; 318 | 319 | /** 320 | * Using an ARM template, provision a bunch of resources 321 | */ 322 | const createDeployment = async (client, resourceGroupName, deployName, templateParam) => { 323 | const templateFile = await readFile(templatePath, { encoding: 'utf-8' }); 324 | const deployParam = { 325 | properties: { 326 | template: JSON.parse(templateFile), 327 | parameters: templateParam, 328 | mode: 'Incremental', 329 | }, 330 | }; 331 | 332 | return await client.deployments.createOrUpdate(resourceGroupName, deployName, deployParam); 333 | }; 334 | 335 | /** 336 | * Format the results into the expected shape 337 | */ 338 | const updateDeploymentJsonFile = async (client, resourceGroupName, deployName, appId, appPwd) => { 339 | const outputs = await client.deployments.get(resourceGroupName, deployName); 340 | if (outputs && outputs.properties && outputs.properties.outputs) { 341 | const outputResult = outputs.properties.outputs; 342 | const applicationResult = { 343 | MicrosoftAppId: appId, 344 | MicrosoftAppPassword: appPwd, 345 | }; 346 | const outputObj = unpackObject(outputResult); 347 | 348 | if (!createAppInsights) { 349 | delete outputObj.applicationInsights; 350 | } 351 | if (!createCosmosDb) { 352 | delete outputObj.cosmosDb; 353 | } 354 | if (!createLuisAuthoringResource && !createLuisResource) { 355 | delete outputObj.luis; 356 | } 357 | if (!createStorage) { 358 | delete outputObj.blobStorage; 359 | } 360 | const result = {}; 361 | Object.assign(result, outputObj, applicationResult); 362 | return result; 363 | } else { 364 | return null; 365 | } 366 | }; 367 | 368 | const provisionFailed = (msg) => { 369 | logger({ 370 | status: BotProjectDeployLoggerType.PROVISION_ERROR, 371 | message: chalk.bold('** Provision failed **'), 372 | }); 373 | }; 374 | 375 | const getErrorMesssage = (err) => { 376 | if (err.body) { 377 | if (err.body.error) { 378 | if (err.body.error.details) { 379 | const details = err.body.error.details; 380 | let errMsg = ''; 381 | for (const detail of details) { 382 | errMsg += detail.message; 383 | } 384 | return errMsg; 385 | } else { 386 | return err.body.error.message; 387 | } 388 | } else { 389 | return JSON.stringify(err.body, null, 2); 390 | } 391 | } else { 392 | return JSON.stringify(err, null, 2); 393 | } 394 | }; 395 | 396 | /** 397 | * Provision a set of Azure resources for use with a bot 398 | */ 399 | const create = async ( 400 | creds, 401 | subId, 402 | name, 403 | location, 404 | environment, 405 | appId, 406 | appPassword, 407 | createLuisResource = true, 408 | createLuisAuthoringResource = true, 409 | createQnAResource = true, 410 | createCosmosDb = true, 411 | createStorage = true, 412 | createAppInsights = true 413 | ) => { 414 | // App insights is a dependency of QnA 415 | if (createQnAResource) { 416 | createAppInsights = true; 417 | } 418 | 419 | const resourceGroupName = resourceGroup; 420 | 421 | // If tenantId is empty string, get tenanId from API 422 | if (!tenantId) { 423 | const token = await creds.getToken(); 424 | const accessToken = token.accessToken; 425 | // the returned access token will almost surely have a tenantId. 426 | // use this as the default if one isn't specified. 427 | if (token.tenantId) { 428 | tenantId = token.tenantId; 429 | logger({ 430 | status: BotProjectDeployLoggerType.PROVISION_INFO, 431 | message: `> Using Tenant ID: ${tenantId}`, 432 | }); 433 | } else { 434 | tenantId = await getTenantId(accessToken); 435 | } 436 | } 437 | 438 | const graphCreds = new msRestNodeAuth.DeviceTokenCredentials( 439 | creds.clientId, 440 | tenantId, 441 | creds.username, 442 | 'graph', 443 | creds.environment, 444 | creds.tokenCache 445 | ); 446 | const graphClient = new GraphRbacManagementClient(graphCreds, tenantId, { 447 | baseUri: 'https://graph.windows.net', 448 | }); 449 | 450 | // If the appId is not specified, create one 451 | if (!appId) { 452 | logger({ 453 | status: BotProjectDeployLoggerType.PROVISION_INFO, 454 | message: '> Creating App Registration ...', 455 | }); 456 | 457 | // create the app registration 458 | const appCreated = await createApp(graphClient, name, appPassword); 459 | if (appCreated === false) { 460 | return provisionFailed(); 461 | } 462 | 463 | // use the newly created app 464 | appId = appCreated.appId; 465 | } 466 | 467 | logger({ 468 | status: BotProjectDeployLoggerType.PROVISION_INFO, 469 | message: `> Create App Id Success! ID: ${appId}`, 470 | }); 471 | 472 | // timestamp will be used as deployment name 473 | const timeStamp = new Date().getTime().toString(); 474 | const client = new ResourceManagementClient(creds, subId); 475 | 476 | // Create a resource group to contain the new resources 477 | try { 478 | const rpres = await createResourceGroup(client, location, resourceGroupName); 479 | } catch (err) { 480 | logger({ 481 | status: BotProjectDeployLoggerType.PROVISION_ERROR, 482 | message: getErrorMesssage(err), 483 | }); 484 | return provisionFailed(); 485 | } 486 | 487 | // Caste the parameters into the right format 488 | const deploymentTemplateParam = getDeploymentTemplateParam( 489 | appId, 490 | appPassword, 491 | location, 492 | name, 493 | createLuisAuthoringResource, 494 | createLuisResource, 495 | createAppInsights, 496 | createCosmosDb, 497 | createStorage 498 | ); 499 | 500 | // Validate the deployment using the Azure API 501 | const validation = await validateDeployment(client, resourceGroupName, timeStamp, deploymentTemplateParam); 502 | 503 | // Handle validation errors 504 | if (validation.error) { 505 | logger({ 506 | status: BotProjectDeployLoggerType.PROVISION_ERROR, 507 | message: `! Error: ${validation.error.message}`, 508 | }); 509 | if (validation.error.details) { 510 | logger({ 511 | status: BotProjectDeployLoggerType.PROVISION_ERROR_DETAILS, 512 | message: JSON.stringify(validation.error.details, null, 2), 513 | }); 514 | } 515 | logger({ 516 | status: BotProjectDeployLoggerType.PROVISION_ERROR, 517 | message: `+ To delete this resource group, run 'az group delete -g ${resourceGroupName} --no-wait'`, 518 | }); 519 | return provisionFailed(); 520 | } 521 | 522 | // Create the entire stack of resources inside the new resource group 523 | // this is controlled by an ARM template identified in templatePath 524 | logger({ 525 | status: BotProjectDeployLoggerType.PROVISION_INFO, 526 | message: `> Deploying Azure services (this could take a while)...`, 527 | }); 528 | const spinner = ora().start(); 529 | try { 530 | const deployment = await createDeployment(client, resourceGroupName, timeStamp, deploymentTemplateParam); 531 | // Handle errors 532 | if (deployment._response.status != 200) { 533 | spinner.fail(); 534 | logger({ 535 | status: BotProjectDeployLoggerType.PROVISION_ERROR, 536 | message: `! Template is not valid with provided parameters. Review the log for more information.`, 537 | }); 538 | logger({ 539 | status: BotProjectDeployLoggerType.PROVISION_ERROR, 540 | message: `! Error: ${validation.error}`, 541 | }); 542 | logger({ 543 | status: BotProjectDeployLoggerType.PROVISION_ERROR, 544 | message: `+ To delete this resource group, run 'az group delete -g ${resourceGroupName} --no-wait'`, 545 | }); 546 | return provisionFailed(); 547 | } 548 | } catch (err) { 549 | spinner.fail(); 550 | logger({ 551 | status: BotProjectDeployLoggerType.PROVISION_ERROR, 552 | message: getErrorMesssage(err), 553 | }); 554 | return provisionFailed(); 555 | } 556 | 557 | var qnaResult = null; 558 | 559 | // Create qna resources, the reason why seperate the qna resources from others: https://github.com/Azure/azure-sdk-for-js/issues/10186 560 | if (createQnAResource) { 561 | const qnaDeployName = new Date().getTime().toString(); 562 | const qnaDeploymentTemplateParam = getQnaTemplateParam(location, name); 563 | const qnaValidation = await validateQnADeployment( 564 | client, 565 | resourceGroupName, 566 | qnaDeployName, 567 | qnaDeploymentTemplateParam 568 | ); 569 | if (qnaValidation.error) { 570 | logger({ 571 | status: BotProjectDeployLoggerType.PROVISION_ERROR, 572 | message: `! Error: ${qnaValidation.error.message}`, 573 | }); 574 | if (qnaValidation.error.details) { 575 | logger({ 576 | status: BotProjectDeployLoggerType.PROVISION_ERROR_DETAILS, 577 | message: JSON.stringify(qnaValidation.error.details, null, 2), 578 | }); 579 | } 580 | logger({ 581 | status: BotProjectDeployLoggerType.PROVISION_ERROR, 582 | message: `+ To delete this resource group, run 'az group delete -g ${resourceGroupName} --no-wait'`, 583 | }); 584 | return provisionFailed(); 585 | } 586 | 587 | // Create qna deloyment 588 | logger({ 589 | status: BotProjectDeployLoggerType.PROVISION_INFO, 590 | message: `> Deploying QnA Resources (this could take a while)...`, 591 | }); 592 | const spinner = ora().start(); 593 | try { 594 | const qnaDeployment = await createQnADeployment( 595 | client, 596 | resourceGroupName, 597 | qnaDeployName, 598 | qnaDeploymentTemplateParam 599 | ); 600 | // Handle errors 601 | if (qnaDeployment._response.status != 200) { 602 | spinner.fail(); 603 | logger({ 604 | status: BotProjectDeployLoggerType.PROVISION_ERROR, 605 | message: `! QnA Template is not valid with provided parameters. Review the log for more information.`, 606 | }); 607 | logger({ 608 | status: BotProjectDeployLoggerType.PROVISION_ERROR, 609 | message: `! Error: ${qnaValidation.error}`, 610 | }); 611 | logger({ 612 | status: BotProjectDeployLoggerType.PROVISION_ERROR, 613 | message: `+ To delete this resource group, run 'az group delete -g ${resourceGroupName} --no-wait'`, 614 | }); 615 | return provisionFailed(); 616 | } 617 | } catch (err) { 618 | spinner.fail(); 619 | logger({ 620 | status: BotProjectDeployLoggerType.PROVISION_ERROR, 621 | message: getErrorMesssage(err), 622 | }); 623 | return provisionFailed(); 624 | } 625 | 626 | const qnaDeploymentOutput = await client.deployments.get(resourceGroupName, qnaDeployName); 627 | if (qnaDeploymentOutput && qnaDeploymentOutput.properties && qnaDeploymentOutput.properties.outputs) { 628 | const qnaOutputResult = qnaDeploymentOutput.properties.outputs; 629 | qnaResult = unpackObject(qnaOutputResult); 630 | } 631 | } 632 | 633 | // If application insights created, update the application insights settings in azure bot service 634 | if (createAppInsights) { 635 | logger({ 636 | status: BotProjectDeployLoggerType.PROVISION_INFO, 637 | message: `> Linking Application Insights settings to Bot Service ...`, 638 | }); 639 | 640 | const appinsightsClient = new ApplicationInsightsManagementClient(creds, subId); 641 | const appInsightsName = name; 642 | const appComponents = await appinsightsClient.components.get(resourceGroupName, appInsightsName); 643 | const appinsightsId = appComponents.appId; 644 | const appinsightsInstrumentationKey = appComponents.instrumentationKey; 645 | const apiKeyOptions = { 646 | name: appInsightsName, 647 | linkedReadProperties: [ 648 | `/subscriptions/${subId}/resourceGroups/${resourceGroupName}/providers/microsoft.insights/components/${appInsightsName}/api`, 649 | `/subscriptions/${subId}/resourceGroups/${resourceGroupName}/providers/microsoft.insights/components/${appInsightsName}/agentconfig`, 650 | ], 651 | linkedWriteProperties: [ 652 | `/subscriptions/${subId}/resourceGroups/${resourceGroupName}/providers/microsoft.insights/components/${appInsightsName}/annotations`, 653 | ], 654 | }; 655 | const appinsightsApiKeyResponse = await appinsightsClient.aPIKeys.create( 656 | resourceGroupName, 657 | appInsightsName, 658 | apiKeyOptions 659 | ); 660 | const appinsightsApiKey = appinsightsApiKeyResponse.apiKey; 661 | 662 | logger({ 663 | status: BotProjectDeployLoggerType.PROVISION_INFO, 664 | message: `> AppInsights AppId: ${appinsightsId} ...`, 665 | }); 666 | logger({ 667 | status: BotProjectDeployLoggerType.PROVISION_INFO, 668 | message: `> AppInsights InstrumentationKey: ${appinsightsInstrumentationKey} ...`, 669 | }); 670 | logger({ 671 | status: BotProjectDeployLoggerType.PROVISION_INFO, 672 | message: `> AppInsights ApiKey: ${appinsightsApiKey} ...`, 673 | }); 674 | 675 | if (appinsightsId && appinsightsInstrumentationKey && appinsightsApiKey) { 676 | const botServiceClient = new AzureBotService(creds, subId); 677 | const botCreated = await botServiceClient.bots.get(resourceGroupName, name); 678 | if (botCreated.properties) { 679 | botCreated.properties.developerAppInsightKey = appinsightsInstrumentationKey; 680 | botCreated.properties.developerAppInsightsApiKey = appinsightsApiKey; 681 | botCreated.properties.developerAppInsightsApplicationId = appinsightsId; 682 | const botUpdateResult = await botServiceClient.bots.update(resourceGroupName, name, botCreated); 683 | 684 | if (botUpdateResult._response.status != 200) { 685 | logger({ 686 | status: BotProjectDeployLoggerType.PROVISION_ERROR, 687 | message: `! Something went wrong while trying to link Application Insights settings to Bot Service Result: ${JSON.stringify( 688 | botUpdateResult 689 | )}`, 690 | }); 691 | throw new Error(`Linking Application Insights Failed.`); 692 | } 693 | logger({ 694 | status: BotProjectDeployLoggerType.PROVISION_INFO, 695 | message: `> Linking Application Insights settings to Bot Service Success!`, 696 | }); 697 | } else { 698 | logger({ 699 | status: BotProjectDeployLoggerType.PROVISION_WARNING, 700 | message: `! The Bot doesn't have a keys properties to update.`, 701 | }); 702 | } 703 | } 704 | } 705 | 706 | spinner.succeed('Success!'); 707 | 708 | // Validate that everything was successfully created. 709 | // Then, update the settings file with information about the new resources 710 | const updateResult = await updateDeploymentJsonFile(client, resourceGroupName, timeStamp, appId, appPassword); 711 | 712 | // Handle errors 713 | if (!updateResult) { 714 | const operations = await client.deploymentOperations.list(resourceGroupName, timeStamp); 715 | if (operations) { 716 | const failedOperations = operations.filter( 717 | (value) => value && value.properties && value.properties.statusMessage.error !== null 718 | ); 719 | if (failedOperations) { 720 | failedOperations.forEach((operation) => { 721 | switch ( 722 | operation && 723 | operation.properties && 724 | operation.properties.statusMessage.error.code && 725 | operation.properties.targetResource 726 | ) { 727 | case 'MissingRegistrationForLocation': 728 | logger({ 729 | status: BotProjectDeployLoggerType.PROVISION_ERROR, 730 | message: `! Deployment failed for resource of type ${operation.properties.targetResource.resourceType}. This resource is not avaliable in the location provided.`, 731 | }); 732 | break; 733 | default: 734 | logger({ 735 | status: BotProjectDeployLoggerType.PROVISION_ERROR, 736 | message: `! Deployment failed for resource of type ${operation.properties.targetResource.resourceType}.`, 737 | }); 738 | logger({ 739 | status: BotProjectDeployLoggerType.PROVISION_ERROR, 740 | message: `! Code: ${operation.properties.statusMessage.error.code}.`, 741 | }); 742 | logger({ 743 | status: BotProjectDeployLoggerType.PROVISION_ERROR, 744 | message: `! Message: ${operation.properties.statusMessage.error.message}.`, 745 | }); 746 | break; 747 | } 748 | }); 749 | } 750 | } else { 751 | logger({ 752 | status: BotProjectDeployLoggerType.PROVISION_ERROR, 753 | message: `! Deployment failed. Please refer to the log file for more information.`, 754 | }); 755 | } 756 | } 757 | 758 | // Merge qna outputs with other resources' outputs 759 | if (createQnAResource) { 760 | if (qnaResult) { 761 | Object.assign(updateResult, qnaResult); 762 | } 763 | } 764 | 765 | return updateResult; 766 | }; 767 | 768 | console.log(chalk.bold('Login to Azure:')); 769 | msRestNodeAuth 770 | .interactiveLogin({ domain: tenantId }) 771 | .then(async (creds) => { 772 | const createResult = await create( 773 | creds, 774 | subId, 775 | name, 776 | location, 777 | environment, 778 | appId, 779 | appPassword, 780 | createLuisResource, 781 | createLuisAuthoringResource, 782 | createQnAResource, 783 | createCosmosDb, 784 | createStorage, 785 | createAppInsights 786 | ); 787 | 788 | if (createResult) { 789 | console.log(''); 790 | console.log( 791 | chalk.bold( 792 | `Your Azure hosting environment has been created! Copy paste the following configuration into a new profile in Composer's Publishing tab.` 793 | ) 794 | ); 795 | console.log(''); 796 | 797 | const token = await creds.getToken(); 798 | const profile = { 799 | accessToken: token.accessToken, 800 | name: name, 801 | environment: environment, 802 | hostname: `${name}`, 803 | luisResource: `${name}-luis`, 804 | settings: createResult, 805 | runtimeIdentifier: 'win-x64', 806 | resourceGroup: resourceGroup, 807 | botName: name, 808 | region: location, 809 | subscriptionId: subId, 810 | }; 811 | 812 | console.log(chalk.white(JSON.stringify(profile, null, 2))); 813 | 814 | console.log(''); 815 | } 816 | }) 817 | .catch((err) => { 818 | console.error(err); 819 | }); 820 | -------------------------------------------------------------------------------- /GPTVirtualAssistant/settings/appsettings.example.json: -------------------------------------------------------------------------------- 1 | { 2 | "openai": { 3 | "account": "***", 4 | "deployment": "***", 5 | "apikey": "***", 6 | "max_messages": 10 7 | }, 8 | "customFunctions": [], 9 | "defaultLanguage": "en-us", 10 | "defaultLocale": "en-us", 11 | "importedLibraries": [], 12 | "languages": [ 13 | "en-us" 14 | ], 15 | "Logging": { 16 | "LogLevel": { 17 | "Default": "Information", 18 | "Microsoft": "Warning", 19 | "Microsoft.Hosting.Lifetime": "Information" 20 | } 21 | }, 22 | "luFeatures": { 23 | "enableCompositeEntities": true, 24 | "enableListEntities": true, 25 | "enableMLEntities": true, 26 | "enablePattern": true, 27 | "enablePhraseLists": true, 28 | "enablePrebuiltEntities": true, 29 | "enableRegexEntities": true 30 | }, 31 | "luis": { 32 | "authoringEndpoint": "", 33 | "authoringRegion": "", 34 | "defaultLanguage": "en-us", 35 | "endpoint": "", 36 | "environment": "composer", 37 | "name": "GPTVirtualAssistant" 38 | }, 39 | "MicrosoftAppId": "", 40 | "publishTargets": [], 41 | "qna": { 42 | "hostname": "", 43 | "knowledgebaseid": "", 44 | "qnaRegion": "westus" 45 | }, 46 | "runtime": { 47 | "command": "dotnet run --project GPTVirtualAssistant.csproj", 48 | "customRuntime": true, 49 | "key": "adaptive-runtime-dotnet-webapp", 50 | "path": "../" 51 | }, 52 | "runtimeSettings": { 53 | "adapters": [], 54 | "features": { 55 | "removeRecipientMentions": false, 56 | "showTyping": false, 57 | "traceTranscript": false, 58 | "useInspection": false, 59 | "setSpeak": { 60 | "voiceFontName": "en-US-JennyNeural", 61 | "fallbackToTextForSpeechIfEmpty": true 62 | } 63 | }, 64 | "components": [], 65 | "skills": { 66 | "allowedCallers": [] 67 | }, 68 | "storage": "", 69 | "telemetry": { 70 | "logActivities": true, 71 | "logPersonalInformation": false, 72 | "options": { 73 | "connectionString": "" 74 | } 75 | } 76 | }, 77 | "skillConfiguration": {}, 78 | "skillHostEndpoint": "http://localhost:3980/api/skills" 79 | } -------------------------------------------------------------------------------- /GPTVirtualAssistant/wwwroot/default.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | GPTVirtualAssistant 8 | 313 | 335 | 336 | 337 | 338 |
339 |
340 |
341 |
GPTVirtualAssistant
342 |
343 |
344 |
345 |
346 |
Your bot is ready!
347 |
You can test your bot in the Bot Framework Emulator
348 | by connecting to http://localhost:3978/api/messages.
349 | 351 |
Visit Azure 352 | Bot Service to register your bot and add it to
353 | various channels. The bot's endpoint URL typically looks 354 | like this:
355 |
https://your_bots_hostname/api/messages
356 |
357 |
358 |
359 |
360 | 361 |
362 | 363 | 364 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Microsoft Corporation. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # AOAI Virtual Assistant Accelerator 2 | 3 | Quickly get started with virtual assistants using Azure OpenAI 4 | 5 | ## Setup 6 | 7 | - Set up an Azure OpenAI resource. You may need to request access if your subscription is not enabled yet 8 | ![Configure AOAI Service](./readme_images/configure-aoai.png) 9 | - Create a GPT 3.5 or GPT 4 deployment 10 | ![Configure AOAI Deployment](./readme_images/configure-deployment.png) 11 | - Clone the repository: 12 | 13 | `git clone https://github.com/microsoft/aoai-virtual-assistant.git` 14 | 15 | - Create the app settings file at `./GPTVirtualAssistant/settings/appsettings.json`. Use the example file provided as a template. You will need to fill in the information in the "openai" field. 16 | ![Configure AOAI Credentials](./readme_images/configure-settings.png) 17 | - Open the project in Bot Framework Composer 18 | ![Configure AOAI Credentials](./readme_images/open-botcomposer.png) 19 | - [Publish your bot](https://learn.microsoft.com/en-us/composer/how-to-publish-bot?tabs=v2x) 20 | ![Publish bot](./readme_images/publish-bot.png) 21 | - [Configure end-user channels](https://learn.microsoft.com/en-us/azure/bot-service/bot-service-manage-channels?view=azure-bot-service-4.0) 22 | ![Configure end-user channels](./readme_images/configure-channels.png) 23 | 24 | ## Contributing 25 | 26 | This project welcomes contributions and suggestions. Most contributions require you to agree to a 27 | Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us 28 | the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com. 29 | 30 | When you submit a pull request, a CLA bot will automatically determine whether you need to provide 31 | a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions 32 | provided by the bot. You will only need to do this once across all repos using our CLA. 33 | 34 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). 35 | For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or 36 | contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. 37 | 38 | ## Trademarks 39 | 40 | This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft 41 | trademarks or logos is subject to and must follow 42 | [Microsoft's Trademark & Brand Guidelines](https://www.microsoft.com/en-us/legal/intellectualproperty/trademarks/usage/general). 43 | Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship. 44 | Any use of third-party trademarks or logos are subject to those third-party's policies. 45 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## Security 4 | 5 | Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/). 6 | 7 | If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://aka.ms/opensource/security/definition), please report it to us as described below. 8 | 9 | ## Reporting Security Issues 10 | 11 | **Please do not report security vulnerabilities through public GitHub issues.** 12 | 13 | Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://aka.ms/opensource/security/create-report). 14 | 15 | If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://aka.ms/opensource/security/pgpkey). 16 | 17 | You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://aka.ms/opensource/security/msrc). 18 | 19 | Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue: 20 | 21 | * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) 22 | * Full paths of source file(s) related to the manifestation of the issue 23 | * The location of the affected source code (tag/branch/commit or direct URL) 24 | * Any special configuration required to reproduce the issue 25 | * Step-by-step instructions to reproduce the issue 26 | * Proof-of-concept or exploit code (if possible) 27 | * Impact of the issue, including how an attacker might exploit the issue 28 | 29 | This information will help us triage your report more quickly. 30 | 31 | If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://aka.ms/opensource/security/bounty) page for more details about our active programs. 32 | 33 | ## Preferred Languages 34 | 35 | We prefer all communications to be in English. 36 | 37 | ## Policy 38 | 39 | Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://aka.ms/opensource/security/cvd). 40 | 41 | 42 | -------------------------------------------------------------------------------- /SUPPORT.md: -------------------------------------------------------------------------------- 1 | # Support 2 | 3 | ## How to file issues and get help 4 | 5 | This project uses GitHub Issues to track bugs and feature requests. Please search the existing 6 | issues before filing new issues to avoid duplicates. For new issues, file your bug or 7 | feature request as a new Issue. 8 | 9 | ## Microsoft Support Policy 10 | 11 | Support for this project is limited to the resources listed above. 12 | -------------------------------------------------------------------------------- /readme_images/configure-aoai.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/aoai-virtual-assistant/c45bc408d313edbde4c3bf80aa8a0e771a1c7b92/readme_images/configure-aoai.png -------------------------------------------------------------------------------- /readme_images/configure-channels.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/aoai-virtual-assistant/c45bc408d313edbde4c3bf80aa8a0e771a1c7b92/readme_images/configure-channels.png -------------------------------------------------------------------------------- /readme_images/configure-deployment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/aoai-virtual-assistant/c45bc408d313edbde4c3bf80aa8a0e771a1c7b92/readme_images/configure-deployment.png -------------------------------------------------------------------------------- /readme_images/configure-settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/aoai-virtual-assistant/c45bc408d313edbde4c3bf80aa8a0e771a1c7b92/readme_images/configure-settings.png -------------------------------------------------------------------------------- /readme_images/open-botcomposer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/aoai-virtual-assistant/c45bc408d313edbde4c3bf80aa8a0e771a1c7b92/readme_images/open-botcomposer.png -------------------------------------------------------------------------------- /readme_images/publish-bot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/aoai-virtual-assistant/c45bc408d313edbde4c3bf80aa8a0e771a1c7b92/readme_images/publish-bot.png --------------------------------------------------------------------------------