Botframework-solutions: [TypeScript] يجب أن تقبل فئة "SkillMiddleware" ثلاث معاملات بدلاً من اثنتين.

تم إنشاؤها على ١٧ أكتوبر ٢٠١٩  ·  13تعليقات  ·  مصدر: microsoft/botframework-solutions

ما المشروع المتأثر؟

Microsoft botframework V4 ، مهارة مخصصة.

بأي لغة هذه؟

المطبوع

ماذا يحدث؟

المهارة غير قادرة على تلقي المعلومات التي تم تمريرها من المساعد الظاهري عبر SkillContext

ما هي خطوات إعادة إظهار هذه المشكلة؟

الخطوة 1: إنشاء VA باستخدام " https://botbuilder.myget.org/feed/aitemplates/package/npm/botbuilder-solutions "
الخطوة 2: قم بتوليد المهارة باستخدام أمر منشئ المهارات
" https://botbuilder.myget.org/feed/aitemplates/package/npm/botbuilder-skills "
الخطوة 3: تمت إضافة ملف بيان المهارة مع معلمة الفتحة
الخطوة 4: اضبط SkillContext باستخدام قيمة معلمة الفتحة.
الخطوة 5: حاول الوصول إلى قيمة SkillContext في Skill.

ماذا كنت تتوقع أن يحدث؟

يجب أن يكون الكائن الذي تم تعيينه في SkillContext متاحًا للمهارة إذا كانت سمة "slot" متطابقة.
لكن المهارة ليست قادرة على الحصول على SkillContext.
يجب أن تدعم "SkillMiddleware" المهارات وتعبئ SkillContext بمعلمات الفتحة.

هل يمكنك مشاركة أي سجلات أو ناتج خطأ وما إلى ذلك؟

بعد القيام ببعض الأعمال ، اكتشف أن CustomSkillAdapter يتم ملؤه بقيمة "SkillsContextAccessor".

الكود الحالي:
تقوم فئة التصدير CustomSkillAdapter بتوسيع SkillHttpBotAdapter {
البناء(
العميل: العميل القياس عن بعد ،
ConversationState: ConversationState،
مهارةContextAccessor: StatePropertyAccessorو
مربع الحوار StateAccessor: StatePropertyAccessorو
...
) {
سوبر (العميل القياس عن بعد) ؛
[...]
this.use (new SkillMiddleware (ConversState، DialStateAccessor)) ؛
[...]
}
}

الرمز المتوقع وفقًا لهذا " https://microsoft.github.io/botframework-solutions/howto/skills/skillenappedav4bot/ "

تقوم فئة التصدير CustomSkillAdapter بتوسيع SkillHttpBotAdapter {
البناء(
العميل: العميل القياس عن بعد ،
ConversationState: ConversationState،
مهارةContextAccessor: StatePropertyAccessorو
مربع الحوار StateAccessor: StatePropertyAccessorو
...
) {
سوبر (العميل القياس عن بعد) ؛
[...]
this.use (new SkillMiddleware (ConversState، SkillsContextAccessor، DialStateAccessor)) ؛
[...]
}
}

شكرا،
إدوارد

Bug

التعليق الأكثر فائدة

من الرائع سماع ذلك! سعيد لأنني استطعت مساعدتك في هذا 😊

ال 13 كومينتر

مرحبًا @ Edwardfelix08 ، نعتذر عن التأخير في الإجابة.
راجعنا الوثائق لتمكين V4 Bot كمهارة (تم تغيير بنية المستند ، وأرجع الرابط السابق 404) وأدركنا أنه لم يتم تحديثه بشكل صحيح بعد بعض التغييرات في الكود ، لذلك سنقوم بتحديث هذه الوثائق.

باتباع خطوات repro الخاصة بك ، نتفهم أن لديك بعض المعلومات عن المساعد الافتراضي الخاص بك وأنك تحفظ هذه المعلومات في SkillContext في المساعد الافتراضي ، وعندما تتلقى المهارة الرسالة ، فأنت تريد استرداد هذه المعلومات من SkillContext . هل هذا صحيح؟

مرحبًاdfavretto.
نعم انه صحيح.

مرحبًا @ Edwardfelix08 ، لقد قمنا باختبار هذا السيناريو ، وقمنا بإنشاء دليل حول كيفية جعل هذا العمل. خذ بعين الاعتبار أن -مساعد عينة ليست مستعدة الخروج من مربع لاستخدامها في هذا السيناريو، لذلك نحن نقدم ثلاث خطوات لبعض التعديلات الطفيفة اللازمة لإنجاز هذا:

  1. [المساعد الافتراضي] احفظ المعلومات في SkillContext
  2. [botbuilder-Skills] تتم تصفية معلومات SkillContext وحفظها في النشاط الدلالي
  3. [المهارة] قم بتعبئة حالة المهارة بمعلومات النشاط الدلالية للنشاط

[المساعد الافتراضي] احفظ المعلومات في SkillContext

بادئ ذي بدء ، يجب عليك قبل إعادة توجيه رسالتك إلى المهارة. ليست هناك حاجة للقيام بذلك على الفور من قبل ، فقد يتم حفظ هذه المعلومات في أي مرحلة أخرى.

  1. داخل mainDialog ، يجب عليك استخدام SkillsContextAccessor لاسترداد SkillContext المطابق

    const sc: SkillContext = await this.skillContextAccessor.get(dc.context, new SkillContext());
    const skillContext: SkillContext = Object.assign(new SkillContext(), sc);
    
  2. الآن بعد أن تم حفظ SkillContext الخاص بك في متغير ، يمكنك الحصول على أي قيمة أو تعيينها. لا تنس أن القيم الموجودة داخل SkillContext عبارة عن زوج من قيم المفاتيح ، لذا تأكد من أن مفاتيحك فريدة إذا كنت لا تريد الكتابة فوق قيمك. يمكنك الآن حفظ أي شيء ، أي قيمة الموقع:

    skillContext.setObj('location', locationObj);
    
  3. وأخيرا، تعيين SkillContext باستخدام skillContextAccessor حتى يتم حفظ هذه المعلومات في userState الخاص بك:

    await this.skillContextAccessor.set(dc.context, skillContext);
    

[botbuilder-Skills] تتم تصفية معلومات SkillContext وحفظها في النشاط الدلالي

بعد حفظ المعلومات في SkillContext ، لا بأس من إعادة توجيه الرسالة إلى Skill ، ولكن قبل أن تصل الرسالة إلى Skill ، سيعالج SkillDialog داخل botbuilder-skills SkillContext أثناء طريقة onBeginDialog ، والتي يتم تنفيذها مرة واحدة فقط عندما يتم استدعاء المهارة لأول مرة.

ستقوم هذه الطريقة تلقائيًا بالخطوات التالية:

  1. يحصل على SkillContext بنفس الطريقة التي فعلنا بها في خطوتنا الأولى.
  2. يتم استهلاك SkillManifest للحصول على الفتحات ، ثم يتم إرسال هذه المعلومات إلى طريقة matchSkillContextToSlots .
  3. داخل طريقة matchSkillContextToSlots ، يتم تقييم SkillContext للعثور على أي مفتاح يطابق مفتاح الفتحات . يتم استخدام كل مفتاح متطابق لحفظ زوج القيمة والمفتاح الخاص بـ SkillContext في SemanticAction .
  4. يتم إعادة توجيه النشاط مع SemanticAction (المعلومات المسترجعة من SkillContext التي تطابق الفتحات ) إلى المهارة المقابلة.

[المهارة] قم بتعبئة حالة المهارة بمعلومات النشاط الدلالية للنشاط

الخطوة الثالثة والأخيرة هي تعبئة SkillState بالمعلومات المرسلة من المساعد الافتراضي بالخطوات التالية:

  1. في Skill ، داخل mainDialog ، هناك طريقة تسمى populateStateFromSemanticAction . تم التعليق على هذه الطريقة ، وكانت قديمة بعض الشيء. أنشأنا [PR # 2669] (مدمج بالفعل) لتحديث هذه الطريقة.
  2. تأكد من تحديث حالة SkillState الخاصة بك ، مع إضافة الخصائص الضرورية.
  3. قم بتعديل populateStateFromSemanticAction حسب الحاجة لأخذ جميع الخصائص من SemanticAction وحفظها في SkillState . في الوقت الحالي ، تبحث الطريقة عن خاصية "الموقع" كمثال ، يمكن تغيير ذلك إلى أي خاصية تريد الوصول إليها:
    typescript if (semanticAction !== undefined && Object.keys(semanticAction.entities) .find((key: string) => key === "location"))
  4. يمكنك الآن الوصول إلى حالة SkillState الخاصة بك داخل

نأمل أن تكون هذه الخطوات مفيدة 😊

مرحبًا @ lauren-mills هل يمكنك التحقق مما إذا كان هذا النهج يبدو صحيحًا؟ 😁

شكرًا dfavretto سيحاول هذا لمعرفة ما إذا كان يعمل.

مرحبًا dfavretto لقد جربت الحل أعلاه ولكنه لم ينجح. ما زلت أرى أنه لا يوجد تحديث أو تغيير في التعليمات البرمجية في فئة "CustomSkillAdapter"

@ Edwardfelix08 هل يمكن أن تشاركنا بالضبط ما هي المشكلة التي تواجهها؟ إليك أيضًا بعض الأسئلة الإرشادية لتحديد كيفية مساعدتك بشكل أفضل:

  1. هل يمكنك إدارة حفظ المعلومات في SkillContext في المساعد الافتراضي الخاص بك؟
  2. هل تم تحديث SkillManifest بالفتحات اللازمة؟
  3. هل يتطابق مفتاح الفتحة مع المفتاح المستخدم لحفظ المعلومات في SkillContext ؟
  4. هل الطريقة populateStateFromSemanticAction في مهارتك غير موصوفة؟

أيضًا ، فيما يتعلق بـ CustomSkillAdapter ، لم تكن هناك حاجة لتغيير هذه الفئة لسيناريو الحالة هذا.

مرحبًا dfavretto ،
أدناه هو الرمز المستخدم

  1. هل يمكنك إدارة حفظ المعلومات في SkillContext في المساعد الافتراضي الخاص بك؟

    حوار VA الرئيسي.
    const sk: SkillContext = await this.skillContextAccessor.get (dc.context، new SkillContext ())؛
    CONST SkillsContext: SkillContext = Object.assign (new SkillContext ()، sk) ؛
    SkillsContext.setObj ('userState' ، ملف تعريف المستخدم) ؛
    في انتظار this.skillContextAccessor.set (dc.context، SkillsContext) ؛

  2. هل تم تحديث SkillManifest الخاص بك بالفتحات اللازمة؟
    المهارات. json في فرجينيا
    "الفتحات": [{
    "الاسم": "حالة المستخدم" ،
    "النوع": ["IUserState"]
    }] ،

    المهارة
    "الفتحات": [{
    "الاسم": "حالة المستخدم" ،
    "النوع": ["IUserState"]
    }] ،

  3. هل يتطابق مفتاح Slot مع المفتاح المستخدم لحفظ المعلومات في SkillContext؟
    كود داخل populateStateFromSemanticAction
    if (SkillsContext.ContainsKey ('userState')) {
    ......
    ......
    }

  4. هل الطريقة populateStateFromSemanticAction في مهارتك غير مذكورة؟
    نعم ، لقد ألغيت التعليق على نموذج الكود populateStateFromSemanticAction في طريقة botSkill.

ما هو إصدار إطار الروبوت الذي يجب أن نستخدمه؟
نحن نستخدم الحزم أدناه.

    "botbuilder": "^4.5.3",
    "botbuilder-ai": "^4.5.3",
    "botbuilder-applicationinsights": "^4.5.3",
    "botbuilder-azure": "^4.5.3",
    "botbuilder-core": "^4.5.3",
    "botbuilder-dialogs": "^4.5.3",
    "botbuilder-skills": "^4.4.6",
    "botbuilder-solutions": "^4.4.6",
    "botframework-config": "^4.5.3",
    "botframework-connector": "^4.5.3",
    "botframework-schema": "^4.5.3",

@ Edwardfelix08 ، أرى أنك تحاول الحصول على القيمة userState من skillContext بالطريقة populateStateFromSemanticAction . أود أن أشير إلى أن skillContext الذي ملأته في المساعد الافتراضي لم يعد هو نفسه الذي تمتلكه في

للاستفادة من هذا الموقف ، يتم نسخ البيانات من المساعد الافتراضي skillContext إلى النشاط semanticAction . النشاط هو العنصر الوحيد المرسل من المساعد الافتراضي إلى المهارة ، ومن ثم يمكن تقييمه للحصول على هذه المعلومات.

في ما يلي مثال على populateStateFromSemanticAction التي ستحصل على userState من النشاط semanticAction :

protected async populateStateFromSemanticAction(context: TurnContext): Promise<void> {
        // Example of populating local state with data passed through semanticAction out of Activity
        const activity: Activity = context.activity;
        const semanticAction: SemanticAction | undefined = activity.semanticAction;
        if (semanticAction !== undefined && Object.keys(semanticAction.entities).find((key: string) => key === "userState")) {

            const userState: any = semanticAction.entities["userState"];
            const userStateObj = userState.properties["userState"];
            const state: SkillState = await this.stateAccessor.get(context, new SkillState());
            state.userState = userStateObj !== undefined ? userStateObj : userState;
            await this.stateAccessor.set(context, state);
        }
    }

dfavretto آسف للرد المتأخر.
لقد حاولت نفس الشيء ولكن ما زلت غير قادر على الحصول على القيمة.
قيمة activity.semanticAction غير محددة.

مرحبًا @ Edwardfelix08 ، لقد أجرينا بعض عمليات التحقق من الصحة ولم نتمكن من SemanticAction دائمًا ما يكون افتراضيًا مع بعض القيمة ، لذلك لا ينبغي أن يكون غير محدد.

image

فقط للتأكيد ، في المساعد الافتراضي الخاص بك ، هل تستدعي مهارتك على النحو التالي؟

image

darrenj - هل يجب أن نضيف فريق الدعم حتى يتمكنوا من المساعدة في التعامل مع هذه المشكلة من منظور آخر؟ نظرًا لأنه لا يبدو أنه لا علاقة له بتنفيذ TypeScript نفسه ، ولكن مع السيناريو المحدد الذي يتم تنفيذه هنا.

مرحبًا dfavretto ،
اسف على الرد متأخرا. لقد تمكنا من الحصول على هذا العمل ، شكرًا لك. كنا نشير إلى الإصدار القديم من إطار العمل بمجرد تحديثه ومراجعته مع التعليمات البرمجية الخاصة بك وكان هناك اختلاف في "populateStateFromSemanticAction" ، وقمنا بتحديث الكود إلى الرمز المقترح وبدأ العمل مثل السحر.

شكرا لك على مساعدتنا في هذا.

من الرائع سماع ذلك! سعيد لأنني استطعت مساعدتك في هذا 😊

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات