BotFramework:将数据从技能传递到虚拟助手

时间:2019-09-26 16:12:27

标签: typescript botframework

我有2个与虚拟助手相关的技能,并且我正在尝试从技能A调用技能B(在技能A的末尾,并且用户没有进一步的操作)。我知道我必须为此通过虚拟助手。我要处理两个问题:

  • 从技能A-> VA传递数据
  • 从VA传递数据->技能B

对于第二个问题,使用带有插槽的SkillContext似乎是the way,但是我似乎找不到第一个问题的解决方案,因为当技能返回到VA时,它全部返回是一个布尔值,指示它是否已完成https://github.com/microsoft/botframework-solutions/blob/853a7ccb940ec2c4d59433b6f2ca2cfa8d5264b4/lib/typescript/botbuilder-skills/src/skillDialog.ts#L229

我试图做的是将我的数据保存在Skill A的SkillContext中,然后在VA中获取该数据并将其传递给SkillB。但是,这只有在Skill A和VA都向相同的Cosmos DB,这并不理想。

有没有更好的解决方案?

2 个答案:

答案 0 :(得分:0)

可以不使用对话框将数据从技能传递到父机器人吗?

我正在使用以下代码片段来调用根机器人的技能

var response = await _skillClient.PostActivityAsync(_botId, targetSkill, _skillsConfig.SkillHostEndpoint, turnContext.Activity, cancellationToken);

我正在使用以下代码段结束技能机器人中的对话

var endOfConversation = Activity.CreateEndOfConversationActivity();
endOfConversation.Code = EndOfConversationCodes.CompletedSuccessfully;

答案 1 :(得分:0)

就我而言,我使用的是 Bot Composer 而不是 PVA。我希望语法是相似的,并且这将同样适用于具有自定义创建技能的 PVA。

我一直在寻求做类似的事情,并且能够使用以下语法获得可行的解决方案。

在我的示例中,我有一个包含 2 个步骤的瀑布式对话框。第一步显示带有几个选项的提示。最后一步检索所选值并结束对话和对话。就我而言,我希望将所选值作为技能的输出返回,以便我可以将其保存到作曲家中的变量中,并在稍后的对话中使用。

我的对话代码是:

public class ActiveFuelCardDialog : ComponentDialog
{
    public ActiveFuelCardDialog() : base(nameof(ActiveFuelCardDialog))
    {
        InitializeWaterfallDialog();
    }

    public WaterfallStepContext StepContext { get; private set; }

    private void InitializeWaterfallDialog()
    {
        var waterFallSteps = new WaterfallStep[]
        {
            CardSelectionStepAsync,
            FinalStepAsync
        };

        AddDialog(new WaterfallDialog($"{nameof(ActiveFuelCardDialog)}.mainFlow", waterFallSteps));
        AddDialog(new ChoicePrompt($"{nameof(ActiveFuelCardDialog)}.cardSelection"));

        InitialDialogId = $"{nameof(ActiveFuelCardDialog)}.mainFlow";
    }

    private async Task<DialogTurnResult> CardSelectionStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
    {
        StepContext = stepContext;
        //then return back a list of 2 cards
        //in the format: CardType
        List<ActiveFuelCardsOutput> activeFuelCardsOutputs = new List<ActiveFuelCardsOutput>();
        activeFuelCardsOutputs.Add(new ActiveFuelCardsOutput()
        {
            CardNo = "1234567890123456",
            CardType = "WM",
            ExpiryDate = DateTime.Now.AddMonths(8)
        });

        activeFuelCardsOutputs.Add(new ActiveFuelCardsOutput()
        {
            CardNo = "2345678901234657",
            CardType = "WM",
            ExpiryDate = DateTime.Now.AddMonths(6)
        });

        activeFuelCardsOutputs.Add(new ActiveFuelCardsOutput()
        {
            CardNo = "3456789012345678",
            CardType = "WM",
            ExpiryDate = DateTime.Now.AddMonths(12)
        });

        return await stepContext.PromptAsync($"{nameof(ActiveFuelCardDialog)}.cardSelection",
            new PromptOptions
            {
                Prompt = MessageFactory.Text("Please select a card"),
                Choices = ChoiceFactory.ToChoices(activeFuelCardsOutputs.Select(x => x.CardNo).ToArray())
            }, cancellationToken);
    }

    private async Task<DialogTurnResult> FinalStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
    {
        StepContext = stepContext;
        string selectedCard = ((FoundChoice)stepContext.Result).Value;

        //https://techcommunity.microsoft.com/t5/teams-developer/skill-dialog-enddialog-does-not-work/m-p/1476612
        await stepContext.Context.SendActivityAsync(new Activity()
        {
            Type = ActivityTypes.EndOfConversation,
            Code = EndOfConversationCodes.CompletedSuccessfully,
            Value = selectedCard
        });

        return await stepContext.EndDialogAsync();
    }
}

导致此功能对我有用的部分是在 FinalStepAsync 方法中

            await stepContext.Context.SendActivityAsync(new Activity()
        {
            Type = ActivityTypes.EndOfConversation,
            Code = EndOfConversationCodes.CompletedSuccessfully,
            Value = selectedCard
        });

        return await stepContext.EndDialogAsync();

这似乎结束了对话并返回了值。

然后我可以通过将技能的“属性”设置为某个变量(例如 dialog.selectedCard)在 Bot Composer 中使用它。然后使用像“${dialog.selectedCard}”这样的值。

这篇文章让我找到了这个答案。 Helpful Post

Showing Conversation calling skill & using value

相关问题