BotFramework: DialogState / DialogStack никогда не заполняется - PullRequest
0 голосов
/ 04 февраля 2019

У нас есть простой бот, который использует диалоги, он работает нормально, но я недавно изменил его, чтобы использовать CosmosDB для хранения состояний, и теперь мы заметили, что dialogStack пуст.

Большая часть кода длябот был взят из примера BotFramework, найденного в репозитории samples .

Состояние пользователя точно обновляется для каждого сообщения, код инициализации выглядит следующим образом:

this.dialogState = conversationState.createProperty(DIALOG_STATE_PROPERTY);
this.dialogAccessor = userState.createProperty(DIALOG_PROPERTY);

this.dialogs = new DialogSet(this.dialogState);
this.dialogs.add(new GreetingDialog(GREETING_DIALOG, this.dialogAccessor));
this.dialogs.add(new PharmacyOrderDialog(PHARMACY_DIALOG, this.dialogAccessor));

this.conversationState = conversationState;
this.userState = userState;

Мы вызываем функцию saveChanges в конце onTurn:

await this.conversationState.saveChanges(context);

Я не могу найти никакой информации о том, что должно быть даже в объекте dialogStack, не говоря уже о решении того, что я считаю ошибкойв нашем коде.

Спасибо за любую помощь.

Редактируйте, добавляя функцию onTurn для большей ясности:

public onTurn = async (context: TurnContext) => {
if (context.activity.type === ActivityTypes.Message) {
  if (context.activity.value) {
    let useridFromCard = context.activity.value.useridList;
    if (context.activity.value.useridList) {
      useridFromCard = context.activity.value.useridList;
    }
    await this.dialogAccessor.set(context, new DialogDetails(useridFromCard));
  }

  let dialogResult: DialogTurnResult;
  const dc = await this.dialogs.createContext(context);
  const results = await this.luisRecognizer.recognize(context);
  const topIntent = LuisRecognizer.topIntent(results);

  const dialogDetails: DialogDetails = await this.dialogAccessor.get(context);
  if (!dialogDetails) {
    await this.dialogAccessor.set(context, new DialogDetails(ENVIRONMENT.USERID, results));
  } else {
    dialogDetails.luisResults = results;
    await this.dialogAccessor.set(context, dialogDetails);
  }
  const interrupted = await this.isTurnInterrupted(dc, results);
  if (interrupted) {
    if (dc.activeDialog !== undefined) {
      await dc.repromptDialog();
    }
  } else {
    dialogResult = await dc.continueDialog();
  }

  if (!dc.context.responded) {
    switch (dialogResult.status) {
      case DialogTurnStatus.empty:
        switch (topIntent) {
          case GREETING_INTENT:
            await dc.beginDialog(GREETING_DIALOG);
            break;
          case PHARMACY_INTENT:
            await dc.beginDialog(PHARMACY_DIALOG);
            break;
          case NONE_INTENT:
            await context.sendActivities(ResponseRandomizer.getRandomResponse(RANDOM_PHRASE_PATH, POST_GREETING_MESSAGE_PHRASE_KEY));
            break;
          default:
            await dc.context.sendActivity("I didn't understand what you just said to me.");
            break;
        }
        break;
      case DialogTurnStatus.waiting:
        // The active dialog is waiting for a response from the user, so do nothing.
        break;
      case DialogTurnStatus.complete:
        // All child dialogs have ended. so do nothing.
        break;
      default:
        // Unrecognized status from child dialog. Cancel all dialogs.
        await dc.cancelAllDialogs();
        break;
    }
  }
} else if (context.activity.type === ActivityTypes.ConversationUpdate) {
  if (context.activity.membersAdded.length !== 0) {
    for (const idx in context.activity.membersAdded) {
      if (context.activity.membersAdded[idx].id !== context.activity.recipient.id) {
        const welcomeCard = CardFactory.adaptiveCard(WelcomeCard);
        await context.sendActivity({ attachments: [welcomeCard] });

        await context.sendActivities(ResponseRandomizer.getRandomResponse
          (RANDOM_PHRASE_PATH, WELCOME_MESSAGE_PHRASE_KEY));
        const useridCard = CardFactory.adaptiveCard(USERIDCard);
        await context.sendActivity({ attachments: [useridCard] });

      }
    }
  }
}
await this.conversationState.saveChanges(context);
await this.userState.saveChanges(context);
}

Цените помощь всем.Может случиться так, что там никогда не должно быть ничего, что хранит информацию о том, как настроен наш бот, но я просто хочу убедиться, что это не ошибка с нашей стороны.

Ответы [ 2 ]

0 голосов
/ 07 февраля 2019

У вас определенно должно быть dialogStack, если вы используете DialogSet или WaterfallDialog.Вот концептуальная информация о диалогах и ссылка SDK .dialogStack для Образец 19 выглядит следующим образом:

enter image description here

Я не вижу ничего плохого в вашей инициализации / конструкторекод, хотя это немного нетрадиционно, поскольку он использует dialogState и dialogAccessor.Однако это не должно вызывать проблем.

Ваш onTurn код также выглядит хорошо, насколько я могу судить.

Это заставляет меня поверить в одну из двух вещей:

  1. Вы смотрите dialogStack, когда нет никаких активных диалогов.dialogStack заполняется только тогда, когда пользователю представлены диалоги, а затем очищается в конце диалога.Не похоже, что у вашего бота проблемыподсказки.

Возможные исправления для # 2, выше:

  1. Вы добавляете dialogDetails к своему userState и затем передаете свой userState к каждому из ваших диалогов.Вы не вызываете запросы от dialogDetails от вашего userState, не так ли?Если это так, это может быть проблемой.Если вы делаете это, ваш dialogStack может появиться в userState вместо conversationState, что не будет оптимальным.Единственный контекст, который вы должны использовать для dialogs / prompts / waterfallDialogs, это контекст, полученный из conversationState, как в вашем this.dialogState = conversationState.createProperty(DIALOG_STATE_PROPERTY);.Поскольку вы определяете свои диалоги с помощью this.dialogs = new DialogSet(this.dialogState);, каждый диалог с add по this.dialogs уже получает правильный контекст и dialogState, как и должно быть - вам просто нужно использовать его в своих диалогах.

  2. Также может быть, что где-то в ваших диалогах вы звоните endDialog или cancelAllDialogs преждевременно.

Если это не такне решите вашу проблему, опубликуйте код одного из диалогов, вызывающих у вас проблемы, и я могу помочь вам устранить эту проблему в дальнейшем.

0 голосов
/ 04 февраля 2019

Во-первых, состояние диалога (его стек и др.) На самом деле является просто черным ящиком в том, что касается вашего собственного кода.Все, что вам нужно сделать, это убедиться, что вы сохраняете контейнер состояния, в котором вы создали свойство для состояния диалога, в котором, в соответствии с тем, что вы сказали выше, вы находитесь (т.е. this.conversationState.saveChanges(context)).

Мне нужно посмотреть, как вы на самом деле вызываете диалоги.Можете ли вы обновить свой вопрос тем, как выглядит ваш onTurn метод ... хотя бы в отношении вашего вызова диалогов?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...