transcriptLogger creating duplicate logs for the Facebook channel

Versions
BotBuilder SDK v4.4.0
node.js v10.16.0
Describe the bug
I have implemented transcripLogger in my chatbot and I have noticed that I am getting duplicate trace logs for the Facebook channel. This isn't happening for the WebChat channel.
The duplicate Facebook channel logs are identical in every way except the filename that they're saved as. They even have the same timestamp.
To Reproduce

Implement transcriptLogger
Connect Facebook channel
Test Facebook channel
Inspect Facebook channel logs

Expected behavior
I expect individual log items for each Facebook channel message
Example duplicate logs
Log 1 - filename:<PHONE_NUMBER>194679-550063992071761/8d724e2af871980-undefined.json
{
    "type": "trace",
    "valueType": "https://www.qnamaker.ai/schemas/trace",
    "name": "QnAMaker",
    "label": "QnAMaker Trace",
    "value": {
        "message": {
            "type": "message",
            "id": "_CF7huafon1rOCx7wJlWxQl_gvSoBeDN7omoMB-fKbqb-SIGqakvdGhzzmqkLIPppW4DEOSHu75XiDYYLcNHng",
            "timestamp": "2019-08-19T20:20:29.150Z",
            "serviceUrl": "https://facebook.botframework.com/",
            "channelId": "facebook",
            "from": {
                "id": "2005698806194679",
                "name": "Sean Betts",
                "role": "user"
            },
            "conversation": {
                "isGroup": false,
                "id": "2005698806194679-550063992071761"
            },
            "recipient": {
                "id": "550063992071761",
                "name": "MiHNDbot"
            },
            "text": "What Types Are There?",
            "channelData": {
                "sender": {
                    "id": "2005698806194679"
                },
                "recipient": {
                    "id": "550063992071761"
                },
                "timestamp":<PHONE_NUMBER>150,
                "message": {
                    "mid": "_CF7huafon1rOCx7wJlWxQl_gvSoBeDN7omoMB-fKbqb-SIGqakvdGhzzmqkLIPppW4DEOSHu75XiDYYLcNHng",
                    "seq": 0,
                    "quick_reply": {
                        "payload": "What Types Are There?"
                    },
                    "text": "What Types Are There...",
                    "is_echo": false
                }
            }
        },
        "queryResults": [
            {
                "questions": [
                    "What types of mental health are there?"
                ],
                "answer": "🙉\nThere are many different mental health problems. Some of them have similar symptoms, so you may experience the symptoms of more than one mental health problem, or be given several diagnoses at once. Or you might not have any particular diagnosis, but still be finding things very difficult. Everyone’s experience is different and can change at different times. Click below to find out more about specific types of mental health problems:",
                "score": 0.7421,
                "id": 123,
                "source": "QnA Tracker - Uploaded 01.08.19.xlsx",
                "metadata": [
                    {
                        "name": "type",
                        "value": "mental health"
                    },
                    {
                        "name": "question",
                        "value": "types"
                    }
                ],
                "context": {
                    "isContextOnly": true,
                    "prompts": [
                        {
                            "displayOrder": 0,
                            "qnaId": 124,
                            "qna": null,
                            "displayText": "Depression"
                        },
                        {
                            "displayOrder": 0,
                            "qnaId": 130,
                            "qna": null,
                            "displayText": "Anxiety"
                        },
                        {
                            "displayOrder": 0,
                            "qnaId": 135,
                            "qna": null,
                            "displayText": "Phobias"
                        },
                        {
                            "displayOrder": 0,
                            "qnaId": 140,
                            "qna": null,
                            "displayText": "Eating Disorders"
                        },
                        {
                            "displayOrder": 0,
                            "qnaId": 146,
                            "qna": null,
                            "displayText": "Schizophrenia"
                        },
                        {
                            "displayOrder": 0,
                            "qnaId": 151,
                            "qna": null,
                            "displayText": "OCD"
                        },
                        {
                            "displayOrder": 0,
                            "qnaId": 166,
                            "qna": null,
                            "displayText": "Personality Disorders"
                        },
                        {
                            "displayOrder": 0,
                            "qnaId": 172,
                            "qna": null,
                            "displayText": "Bipolar"
                        },
                        {
                            "displayOrder": 0,
                            "qnaId": 156,
                            "qna": null,
                            "displayText": "Panic Disorder"
                        },
                        {
                            "displayOrder": 0,
                            "qnaId": 184,
                            "qna": null,
                            "displayText": "Psychosis"
                        }
                    ]
                }
            }
        ],
        "knowledgeBaseId": "634a06fe-78f9-44e4-b675-4fe53e4e62d9",
        "scoreThreshold": 0.3,
        "top": 1,
        "strictFilters": [],
        "metadataBoost": []
    },
    "channelId": "facebook",
    "serviceUrl": "https://facebook.botframework.com/",
    "conversation": {
        "isGroup": false,
        "id": "2005698806194679-550063992071761"
    },
    "from": {
        "id": "550063992071761",
        "name": "MiHNDbot"
    },
    "recipient": {
        "id": "2005698806194679",
        "name": "Sean Betts",
        "role": "user"
    },
    "replyToId": "_CF7huafon1rOCx7wJlWxQl_gvSoBeDN7omoMB-fKbqb-SIGqakvdGhzzmqkLIPppW4DEOSHu75XiDYYLcNHng",
    "timestamp": "2019-08-19T20:20:32.229Z"
}

Log 2 - filename:<PHONE_NUMBER>194679-550063992071761/8d724e2afb1fa00-undefined.json
{
    "type": "trace",
    "valueType": "https://www.qnamaker.ai/schemas/trace",
    "name": "QnAMaker",
    "label": "QnAMaker Trace",
    "value": {
        "message": {
            "type": "message",
            "id": "_CF7huafon1rOCx7wJlWxQl_gvSoBeDN7omoMB-fKbqb-SIGqakvdGhzzmqkLIPppW4DEOSHu75XiDYYLcNHng",
            "timestamp": "2019-08-19T20:20:29.150Z",
            "serviceUrl": "https://facebook.botframework.com/",
            "channelId": "facebook",
            "from": {
                "id": "2005698806194679",
                "name": "Sean Betts",
                "role": "user"
            },
            "conversation": {
                "isGroup": false,
                "id": "2005698806194679-550063992071761"
            },
            "recipient": {
                "id": "550063992071761",
                "name": "MiHNDbot"
            },
            "text": "What Types Are There?",
            "channelData": {
                "sender": {
                    "id": "2005698806194679"
                },
                "recipient": {
                    "id": "550063992071761"
                },
                "timestamp":<PHONE_NUMBER>150,
                "message": {
                    "mid": "_CF7huafon1rOCx7wJlWxQl_gvSoBeDN7omoMB-fKbqb-SIGqakvdGhzzmqkLIPppW4DEOSHu75XiDYYLcNHng",
                    "seq": 0,
                    "quick_reply": {
                        "payload": "What Types Are There?"
                    },
                    "text": "What Types Are There...",
                    "is_echo": false
                }
            }
        },
        "queryResults": [
            {
                "questions": [
                    "What types of mental health are there?"
                ],
                "answer": "🙉\nThere are many different mental health problems. Some of them have similar symptoms, so you may experience the symptoms of more than one mental health problem, or be given several diagnoses at once. Or you might not have any particular diagnosis, but still be finding things very difficult. Everyone’s experience is different and can change at different times. Click below to find out more about specific types of mental health problems:",
                "score": 0.7421,
                "id": 123,
                "source": "QnA Tracker - Uploaded 01.08.19.xlsx",
                "metadata": [
                    {
                        "name": "type",
                        "value": "mental health"
                    },
                    {
                        "name": "question",
                        "value": "types"
                    }
                ],
                "context": {
                    "isContextOnly": true,
                    "prompts": [
                        {
                            "displayOrder": 0,
                            "qnaId": 124,
                            "qna": null,
                            "displayText": "Depression"
                        },
                        {
                            "displayOrder": 0,
                            "qnaId": 130,
                            "qna": null,
                            "displayText": "Anxiety"
                        },
                        {
                            "displayOrder": 0,
                            "qnaId": 135,
                            "qna": null,
                            "displayText": "Phobias"
                        },
                        {
                            "displayOrder": 0,
                            "qnaId": 140,
                            "qna": null,
                            "displayText": "Eating Disorders"
                        },
                        {
                            "displayOrder": 0,
                            "qnaId": 146,
                            "qna": null,
                            "displayText": "Schizophrenia"
                        },
                        {
                            "displayOrder": 0,
                            "qnaId": 151,
                            "qna": null,
                            "displayText": "OCD"
                        },
                        {
                            "displayOrder": 0,
                            "qnaId": 166,
                            "qna": null,
                            "displayText": "Personality Disorders"
                        },
                        {
                            "displayOrder": 0,
                            "qnaId": 172,
                            "qna": null,
                            "displayText": "Bipolar"
                        },
                        {
                            "displayOrder": 0,
                            "qnaId": 156,
                            "qna": null,
                            "displayText": "Panic Disorder"
                        },
                        {
                            "displayOrder": 0,
                            "qnaId": 184,
                            "qna": null,
                            "displayText": "Psychosis"
                        }
                    ]
                }
            }
        ],
        "knowledgeBaseId": "634a06fe-78f9-44e4-b675-4fe53e4e62d9",
        "scoreThreshold": 0.3,
        "top": 1,
        "strictFilters": [],
        "metadataBoost": []
    },
    "channelId": "facebook",
    "serviceUrl": "https://facebook.botframework.com/",
    "conversation": {
        "isGroup": false,
        "id": "2005698806194679-550063992071761"
    },
    "from": {
        "id": "550063992071761",
        "name": "MiHNDbot"
    },
    "recipient": {
        "id": "2005698806194679",
        "name": "Sean Betts",
        "role": "user"
    },
    "replyToId": "_CF7huafon1rOCx7wJlWxQl_gvSoBeDN7omoMB-fKbqb-SIGqakvdGhzzmqkLIPppW4DEOSHu75XiDYYLcNHng",
    "timestamp": "2019-08-19T20:20:32.510Z"
}

[bug]

@seanbetts, the current version of Botbuilder is v4.5.3. Have you tried updating the package and testing? In the mean time, I will attempt to repro here and will let you know what I find.

I'm unable to repro the issue as I am only receiving one QnA trace log over Facebook. I tested with v4.4.0 as well as v4.5.3.
Can you post any relevant code so I can better diagnose? I'm interested in how you are calling the transcript logger, how state is being instantiated, used, and saved, and where values are being passed into QnA and returned in your dialog(s).

Hi @stevkan - thank you for looking into this. Below is a copy of my index.js file that shows how I'm calling the transcript logger:
// Import required pckages
const path = require('path');
const restify = require('restify');

// Import required bot services.
const { BotFrameworkAdapter, MemoryStorage, ConversationState, UserState } = require('botbuilder');
const { BotConfiguration } = require('botframework-config');

// Import middleware for transcript logging
const { TranscriptLoggerMiddleware } = require('botbuilder-core'); // ConsoleTranscriptLogger,

// Import storage for transcript
const { AzureBlobTranscriptStore } = require('botbuilder-azure');

// Enable Application Insights
const appInsights = require('applicationinsights');
appInsights.setup('b91c8f19-39fc-4b5d-a7e5-b9cf26a4030d')
    .setUseDiskRetryCaching(true)
    .start();

// This bot's main dialog.
const { DialogBot } = require('./bots/dialogBot');

// Read botFilePath and botFileSecret from .env file
const ENV_FILE = path.join(__dirname, '.env');
require('dotenv').config({ path: ENV_FILE });

// Get the .bot file path
const BOT_FILE = path.join(__dirname, (process.env.botFilePath || ''));
let botConfig;
try {
    // Read bot configuration from .bot file.
    botConfig = BotConfiguration.loadSync(BOT_FILE, process.env.botFileSecret);
} catch (err) {
    console.error(`Error reading bot file. Please ensure you have valid botFilePath and botFileSecret set for your environment.`);
    process.exit();
}

// For local development configuration as defined in .bot file
const DEV_ENVIRONMENT = 'development';

// Name of Transcript Blob Type service within the .bot file
const BLOB_TRANSCRIPT_CONFIGURATION = 'BlobTranscriptStorage';

// Name of Console Logs Blob Type service within the .bot file
// const BLOB_CONSOLE_LOGS_CONFIGURATION = 'BlobConsoleLogStorage';

// Define name of the endpoint configuration section from the .bot file
const BOT_CONFIGURATION = (process.env.NODE_ENV || DEV_ENVIRONMENT);

// Get bot endpoint configuration by service name - Bot configuration as defined in .bot file
const endpointConfig = botConfig.findServiceByNameOrId(BOT_CONFIGURATION);

// Create bot adapter
const adapter = new BotFrameworkAdapter({
    appId: process.env.microsoftAppId, // || endpointConfig.appId,
    appPassword: process.env.microsoftAppPassword // || endpointConfig.appPassword
});

// Catch-all for errors.
adapter.onTurnError = async (context, error) => {
    // This check writes out errors to console log
    // NOTE: In production environment, you should consider logging this to Azure
    //       application insights.
    console.error(`\n [onTurnError]: ${ error }`);
    // Send a message to the user
    await context.sendActivity(`😬/nOops. Something went wrong! Please try asking me something else.`);
    // Clear out state
    await conversationState.delete(context);
};

// Get blob service configuration for transcripts and console logs as defined in .bot file
const blobTranscriptStorageConfig = botConfig.findServiceByNameOrId(BLOB_TRANSCRIPT_CONFIGURATION);
// const blobConsoleLogsStorageConfig = botConfig.findServiceByNameOrId(BLOB_CONSOLE_LOGS_CONFIGURATION);

// The transcript store has methods for saving and retrieving bot conversation transcripts.
let transcriptStore = new AzureBlobTranscriptStore({
    storageAccountOrConnectionString: blobTranscriptStorageConfig.connectionString,
    containerName: blobTranscriptStorageConfig.container
});

// Create the middleware layer responsible for logging incoming and outgoing activities into the transcript store.
var transcriptMiddleware = new TranscriptLoggerMiddleware(transcriptStore);
adapter.use(transcriptMiddleware);

// The transcript store has methods for saving and retrieving bot console logs.
// let consoleLogStore = new AzureBlobTranscriptStore({
//     storageAccountOrConnectionString: blobConsoleLogsStorageConfig.connectionString,
//     containerName: blobConsoleLogsStorageConfig.container
// });

// Create the middleware layer responsible for logging console messages in the transcript store
// var consoleLogMiddleware = new ConsoleTranscriptLogger(consoleLogStore);
// adapter.use(consoleLogMiddleware);

// Define state store for your bot.
// See https://aka.ms/about-bot-state to learn more about bot state.
const memoryStorage = new MemoryStorage();

// Create conversation and user state with in-memory storage provider.
const conversationState = new ConversationState(memoryStorage);
const userState = new UserState(memoryStorage);

// CAUTION: You must ensure your product environment has the NODE_ENV set
//          to use the Azure Blob storage or Azure Cosmos DB providers.

// Add botbuilder-azure when using any Azure services.
// const { BlobStorage } = require('botbuilder-azure');

// Get service configuration
// const blobStorageConfig = botConfig.findServiceByNameOrId(STORAGE_CONFIGURATION_ID);
// const blobStorage = new BlobStorage({
//     containerName: (blobStorageConfig.container || DEFAULT_BOT_CONTAINER),
//     storageAccountOrConnectionString: blobStorageConfig.connectionString,
// });
// conversationState = new ConversationState(blobStorage);
// userState = new UserState(blobStorage);

// Pass in a logger to the bot. For this sample, the logger is the console, but alternatives such as Application Insights and Event Hub exist for storing the logs of the bot.
const logger = console;

// Create the main dialog.
// const dialog = new UserProfileDialog(userState, logger);
const bot = new DialogBot(conversationState, userState, logger, transcriptStore);

// Create HTTP server
let server = restify.createServer();
server.listen(process.env.port || process.env.PORT || 3978, function() {
    console.log(`\n${ server.name } listening to ${ server.url }`);
    console.log(`\nGet Bot Framework Emulator: https://aka.ms/botframework-emulator`);
});

// Listen for incoming activities and route them to your bot main dialog.
server.post('/api/messages', (req, res) => {
    // Route received a request to adapter for processing
    adapter.processActivity(req, res, async (turnContext) => {
        // route to bot activity handler.
        await bot.run(turnContext);
    });
});

Below is my dialog.js that manages the dialog:
const { ActivityHandler, ActivityTypes } = require('botbuilder');
const { CardFactory } = require('botbuilder-core');
const { QnAMaker } = require('botbuilder-ai');

// const CONVERSATION_DATA_PROPERTY = 'conversationData';
// const USER_PROFILE_PROPERTY = 'userProfile';

const WelcomeCard = require('../resources/welcomeCard.json');
const fbCards = require('../resources/fbCards.js');
const fbBot = require('../bots/fbBot.js');
// const teamsWelcomeCard = require('../resources/teamsWelcomeCard.json');

// initialized to access values in .env file.
var dotenv = require('dotenv');
dotenv.config();

var sendTyping = async function(context) {
    await context.sendActivities([
        { type: 'typing' },
        { type: 'delay', value: 2000 }
    ]);
};

class DialogBot extends ActivityHandler {
    constructor(conversationState, userState, dialog, logger) {
        super();

        // Create the state property accessors for the conversation data and user profile.
        // this.conversationData = conversationState.createProperty(CONVERSATION_DATA_PROPERTY);
        // this.userProfile = userState.createProperty(USER_PROFILE_PROPERTY);

        // The state management objects for the conversation and user state.
        // this.conversationState = conversationState;
        // this.userState = userState;

        if (!conversationState) throw new Error('[DialogBot]: Missing parameter. conversationState is required');
        if (!userState) throw new Error('[DialogBot]: Missing parameter. userState is required');
        if (!dialog) throw new Error('[DialogBot]: Missing parameter. dialog is required');
        if (!logger) {
            logger = console;
            logger.log('[DialogBot]: logger not passed in, defaulting to console');
        }

        try {
            this.qnaMaker = new QnAMaker({
                knowledgeBaseId: process.env.QnAKnowledgebaseId,
                endpointKey: process.env.QnAAuthKey,
                host: process.env.QnAEndpointHostName
            });
        } catch (err) {
            logger.warn(`QnAMaker Exception: ${ err } Check your QnAMaker configuration in .env`);
        }

        this.conversationState = conversationState;
        this.userState = userState;
        this.dialog = dialog;
        this.logger = logger;
        this.dialogState = this.conversationState.createProperty('DialogState');

        // If a new user is added to the conversation, send them a greeting message
        this.onMembersAdded(async (context, next) => {
            await sendTyping(context);
            const membersAdded = context.activity.membersAdded;
            for (let cnt = 0; cnt < membersAdded.length; cnt++) {
                if (membersAdded[cnt].id !== context.activity.recipient.id) {
                    const welcomeCard = CardFactory.adaptiveCard(WelcomeCard);
                    await context.sendActivity({ attachments: [welcomeCard] });
                }
            }

            // By calling next() you ensure that the next BotHandler is run.
            await next();
        });

        // When a user sends a message, perform a call to the QnA Maker service to retrieve matching Question and Answer pairs.
        this.onMessage(async (context, next) => {
            await sendTyping(context);
            console.log('Processing a Message Activity');

            const qnaResults = await this.qnaMaker.getAnswers(context);

            // Show choices if the Facebook Payload from ChannelData is not handled
            if (!await fbBot.processFacebookPayload(context, context.activity.channelData)) {
                // detect if Facebook Messenger is the channel being used
                if (context.activity.channelId === 'facebook') {
                    let facebookPayload = context.activity.channelData;
                    let fbSender = facebookPayload.sender;
                    var fbPSID = fbSender.id;
                    if (qnaResults[0]) {
                        const { answer, context: { prompts } } = qnaResults[0];

                        // set a variable for the prompts array from QnA
                        var qnaPrompts = null;
                        if (qnaResults[0].context != null) {
                            qnaPrompts = qnaResults[0].context.prompts;
                        }

                        // map the prompts to the required format for quick_replies channelData
                        var qnaPromptsArray = qnaPrompts.map(obj => {
                            return { content_type: 'text', title: obj.displayText, payload: obj.displayText };
                        });

                        let reply;
                        if (prompts.length) {
                            const quickReply = {
                                channelData: {
                                    text: answer,
                                    quick_replies: qnaPromptsArray
                                }
                            };
                            reply = quickReply;
                        } else {
                            reply = {
                                channelData: {
                                    text: answer
                                }
                            };
                        }

                        await context.sendActivity(reply);

                        // If no answers were returned from QnA Maker, reply with help.
                    } else {
                        let errorCardFB = await fbCards.getErrorCardFB(fbPSID);
                        await context.sendActivity(errorCardFB);
                    }
                } else {
                // If an answer was received from QnA Maker, send the answer back to the user.
                    if (qnaResults[0]) {
                        const { answer, context: { prompts } } = qnaResults[0];

                        let reply;
                        if (prompts.length) {
                            const card = {
                                'type': 'AdaptiveCard',
                                'body': [
                                    {
                                        'type': 'TextBlock',
                                        'text': answer,
                                        wrap: true
                                    }
                                ],
                                'actions': prompts.map(({ displayText }) => ({ type: 'Action.Submit', title: displayText, data: displayText })),
                                '$schema': 'http://adaptivecards.io/schemas/adaptive-card.json',
                                'version': '1.1'
                            };

                            reply = { attachments: [CardFactory.adaptiveCard(card)] };
                        } else {
                            reply = answer;
                        }

                        await context.sendActivity(reply);

                        // If no answers were returned from QnA Maker, reply with help.
                    } else {
                        await context.sendActivity('I\'m sorry, I don\'t have an answer for that. Please ask me something else, such as: \n\n "What Is Mental Health?" \n\n "What Is NeuroDiversity" \n\n "Help"');
                    }
                }
            }

            // By calling next() you ensure that the next BotHandler is run.
            await next();
        });

        this.onEvent(async (turnContext) => {
            console.log('Processing an Event Activity.');

            // Analyze Facebook payload from EventActivity.Value
            await fbBot.processFacebookPayload(turnContext, turnContext.activity.value);
        });

        this.onDialog(async (context, next) => {
            // Save any state changes. The load happened during the execution of the Dialog.
            await this.conversationState.saveChanges(context, false);
            await this.userState.saveChanges(context, false);
            await next();
        });
    }
}

module.exports.DialogBot = DialogBot;

Finally, below is the customised code for the Facebook channel:
const { QnAMaker } = require('botbuilder-ai');
const fbCards = require('../resources/fbCards.js');

var qnaMaker = new QnAMaker({
    knowledgeBaseId: process.env.QnAKnowledgebaseId,
    endpointKey: process.env.QnAAuthKey,
    host: process.env.QnAEndpointHostName
});

// Customisation code for Facebook Messenger

// Process a Facebook payload from channel data, to handle optin events, postbacks and quick replies.
const processFacebookPayload = async function(turnContext, data) {
    // At this point we know we are on Facebook channel, and can consume the Facebook custom payload present in channelData.
    const facebookPayload = data;
    if (facebookPayload) {
        if (facebookPayload.postback) {
            // Postback
            await this.onFacebookPostback(turnContext, facebookPayload.postback, facebookPayload.sender);
            return true;
        } else if (facebookPayload.optin) {
            // Optin
            await this.onFacebookOptin(turnContext, facebookPayload.optin);
            return true;
        } else if (facebookPayload.message && facebookPayload.message.quick_reply) {
            // Quick Reply
            await this.onFacebookQuickReply(turnContext, facebookPayload.message.quick_reply, facebookPayload.sender);
            return true;
        }
    }
    return false;
};

// Called when receiving a Facebook messaging_postback event. Facebook Developer Reference: Postback - https://developers.facebook.com/docs/messenger-platform/reference/webhook-events/messaging_postbacks/
const onFacebookPostback = async function(turnContext, postback, sender) {
    console.log('Facebook Postback message received.');
    var fbPSID = sender.id;

    // PostBack handling logic
    if (postback.payload === 'GET_STARTED') {
        let welcomeCardFB = await fbCards.getWelcomeCardFB(fbPSID);
        await turnContext.sendActivity(welcomeCardFB);
    } else {
        if (postback.payload === 'GET_HELP') {
            let helpCardFB = await fbCards.getHelpCardFB(fbPSID);
            await turnContext.sendActivity(helpCardFB);
        } else {
            if (postback.payload === 'WHAT_IS_MENTAL_HEALTH') {
                // qnaMaker.getAnswers doesn't accept string input, so we need to adjust our turnContext
                // to match what it expects, which is a string in Activity.Text
                turnContext.activity.text = postback.payload;

                // call the QnA
                const qnaResults = await qnaMaker.getAnswers(turnContext);

                // If an answer was received from QnA Maker, send the answer back to the user.
                if (qnaResults[0]) {
                    const { answer, context: { prompts } } = qnaResults[0];

                    // set a variable for the prompts array from QnA
                    var qnaPrompts = null;
                    if (qnaResults[0].context != null) {
                        qnaPrompts = qnaResults[0].context.prompts;
                    }

                    // map the prompts to the required format for quick_replies channelData
                    var qnaPromptsArray = qnaPrompts.map(obj => {
                        return { content_type: 'text', title: obj.displayText, payload: obj.displayText };
                    });

                    let reply;
                    if (prompts.length) {
                        const quickReply = {
                            channelData: {
                                text: answer,
                                quick_replies: qnaPromptsArray
                            }
                        };
                        reply = quickReply;
                    } else {
                        reply = {
                            channelData: {
                                text: answer
                            }
                        };
                    }
                    await turnContext.sendActivity(reply);

                    // If no answers were returned from QnA Maker, reply with help.
                } else {
                    await turnContext.sendActivity('No QnA Maker answers were found.');
                }
            } else {
                if (postback.payload === 'WHAT_IS_NEURODIVERSITY') {
                    // qnaMaker.getAnswers doesn't accept string input, so we need to adjust our turnContext
                    // to match what it expects, which is a string in Activity.Text
                    turnContext.activity.text = postback.payload;

                    // call the QnA
                    const qnaResults = await qnaMaker.getAnswers(turnContext);

                    // If an answer was received from QnA Maker, send the answer back to the user.
                    if (qnaResults[0]) {
                        const { answer, context: { prompts } } = qnaResults[0];

                        // set a variable for the prompts array from QnA
                        var qnaPrompts = null;
                        if (qnaResults[0].context != null) {
                            qnaPrompts = qnaResults[0].context.prompts;
                        }

                        // map the prompts to the required format for quick_replies channelData
                        var qnaPromptsArray = qnaPrompts.map(obj => {
                            return { content_type: 'text', title: obj.displayText, payload: obj.displayText };
                        });

                        let reply;
                        if (prompts.length) {
                            const quickReply = {
                                channelData: {
                                    text: answer,
                                    quick_replies: qnaPromptsArray
                                }
                            };
                            reply = quickReply;
                        } else {
                            reply = {
                                channelData: {
                                    text: answer
                                }
                            };
                        }
                        await turnContext.sendActivity(reply);

                        // If no answers were returned from QnA Maker, reply with help.
                    } else {
                        let errorCardFB = await fbCards.getErrorCardFB(fbPSID);
                        await turnContext.sendActivity(errorCardFB);
                    }
                } else {
                    if (postback.payload === 'TEXT_SHOUT') {
                        await turnContext.sendActivity(fbCards.shoutCardFB);
                    } else {
                        if (postback.payload === 'TEXT_SHOUT_NOW') {
                            await turnContext.sendActivity('To get help from Shout please text SHOUT to 85258');
                        } else {
                            if (postback.payload === 'CALL_THE_NHS') {
                                await turnContext.sendActivity(fbCards.nhsCardFB);
                            } else {
                                if (postback.payload === 'CALL_THE_SAMARITANS') {
                                    await turnContext.sendActivity(fbCards.samaritansCardFB);
                                } else {
                                    await turnContext.sendActivity('Facebook PostBack not defined...YET!');
                                }
                            }
                        }
                    }
                }
            }
        }
    }
};

// Called when receiving a Facebook messaging_optin event. Facebook Developer Reference: Optin - https://developers.facebook.com/docs/messenger-platform/reference/webhook-events/messaging_optins/
const onFacebookOptin = async function(turnContext, optin) {
    console.log('Optin message received.');
    // TODO: Your optin handling logic here...
};

// Called when receiving a Facebook quick reply. Facebook Developer Reference: Quick reply - https://developers.facebook.com/docs/messenger-platform/send-messages/quick-replies/
const onFacebookQuickReply = async function(turnContext, quickReply, sender) {
    console.log('Facebook QuickReply message received.');
    var fbPSID = sender.id;

    // qnaMaker.getAnswers doesn't accept string input, so we need to adjust our turnContext
    // to match what it expects, which is a string in Activity.Text
    turnContext.activity.text = quickReply.payload;

    // call the QnA
    const qnaResults = await qnaMaker.getAnswers(turnContext);

    // If an answer was received from QnA Maker, send the answer back to the user.
    if (qnaResults[0]) {
        const { answer, context: { prompts } } = qnaResults[0];

        // set a variable for the prompts array from QnA
        var qnaPrompts = null;
        if (qnaResults[0].context != null) {
            qnaPrompts = qnaResults[0].context.prompts;
        }

        // map the prompts to the required format for quick_replies channelData
        var qnaPromptsArray = qnaPrompts.map(obj => {
            return { content_type: 'text', title: obj.displayText, payload: obj.displayText };
        });

        let reply;
        if (prompts.length) {
            const quickReply = {
                channelData: {
                    text: answer,
                    quick_replies: qnaPromptsArray
                }
            };
            reply = quickReply;
        } else {
            reply = {
                channelData: {
                    text: answer
                }
            };
        }
        await turnContext.sendActivity(reply);
    } else {
        let errorCardFB = await fbCards.getErrorCardFB(fbPSID);
        await turnContext.sendActivity(errorCardFB);
    }
};

module.exports = {
    processFacebookPayload: processFacebookPayload,
    onFacebookPostback: onFacebookPostback,
    onFacebookOptin: onFacebookOptin,
    onFacebookQuickReply: onFacebookQuickReply
};

@seanbetts, I noticed an issue that is tied to the parameters you are passing in to your bot and how they are aligned to the parameters in the bot's constructor.
In your index.js file, you have opted not to create a dialog and are passing in the transcriptStore. Normally, the file would look something like this:
logger = console;

// Create the main dialog.
const dialog = new MainDialog('MainDialog', userState, conversationState);
const bot = new DialogBot(conversationState, userState, dialog, logger);

However, with the removal of dialog and the addition of transcriptStore, the order has changed. Additionally, the transcriptStore is part of the middleware you already have instantiated earlier in your code. Passing it here is unnecessary and should be removed.
logger = console;

// Create the main dialog.
// const dialog = new UserProfileDialog(userState, logger);
const bot = new DialogBot(conversationState, userState, logger, transcriptStore);

In your dialog.js file, your constructor remains unchanged. Hence, you are passing the console logger in for the dialog and the transcriptStore in as your logger.
class DialogBot extends ActivityHandler {
    constructor(conversationState, userState, dialog, logger) {
	    [...]
    }
}

Try removing transcriptStore from inside the index.js const bot assignment and the dialog property from the constructor.
That being said, in your index.js file, you assign const {DialogBot} = require('./bots/dialogBot') but the file you list above is dialog.js which, unless I'm missing it, isn't called. I'm not fully understanding how your bot is structured. From what I can see, your bot should fail altogether.

Hi @stevkan thanks for getting back to me. Apologies, my dialog file is in fact called dialogBot.js, I'll update my post. Thank you as well for the suggestions on the dialog property, that was left over from some earlier testing and I've now removed it from both the index.js and dialogBot.js files. Despite the issues you've pointed out, my chat bot has actually been running. I've just been checking the logs and I do get the following error when the chatbot first starts: OPTIONS /api/messages 405 Method Not Allowed. Could this have something to do with the transcript duplication? I have also noticed another error in the console when using the Facebook Messenger channel 500 ERROR - Error: BotFrameworkAdapter.sendActivity(): missing conversation id.. This is probably a more likely cause of the transcripts duplication so I'm going to do some more investigating.

The 500 ERROR indicates an error in the bot's code. Have you tried debugging, running the bot locally but through a tunnel (ngrok or service bus)? Then you can test on different channels stepping through the code looking for the error(s) to occur.

Thanks @stevkan - this is the same issue that I raised here. I thought that was solved when I checked my Facebook credentials but I've double checked them again and all is in order. From doing some further investigation I am receiving this error whenever I send a postback or quick reply back to Facebook Messenger. Could it be something to do with the way BotFramework and the Facebook Messenger channel are integrated? I've checked my Facebook channel configuration and it is showing issues with the same timestamp as when I have been sending messages. The error message is There was an error sending this message to your bot: HTTP status code InternalServerError I've also checked on Facebook's side and they are logging errors with the same timestamp as well that states The requested URL returned error: 503 Service Unavailable

Could it be related to the Connector Service as referenced here?

Can you list for me the web hooks are you subscribed to?

Sure, I've got them all selected:

messages
messaging_postbacks
messaging_optins
message_deliveries
message_reads
messaging_payments
messaging_pre_checkouts
messaging_checkout_updates
messaging_account_linking
messaging_referrals
message_echoes
messaging_game_plays
standby
messaging_handovers
messaging_policy_enforcement

I'm guessing I don't need all of these enabled and that may be causing the problem?
Thanks for taking the time to look at this

Hi @stevkan I've turned off all the web hooks except the basic ones - messages, messaging_postbacks, message_deliveries and messaging_optins and this seems to have fixed the problem

Sorry, I've just double checked and I'm still getting duplicated logs from the Facebook channel. Changing the web hooks has solved errors but not the log duplication

How about the type of events being logged? The logs you include show trace events. Is it specific to that type or does it matter?

It’s just the trace events that are duplicated

Ok, two things:

As I've seen "log file" and "event" referenced, it is the log file, which contains only trace events, that is duplicating, correct?
If you haven't already, can you please add the Facebook service url (https://facebook.botframework.com) as a trusted service url? This can be done by entering code such as the following in your "dialogBot.js" file (or similar). This can help mitigate some errors which you had listed, previously. I understand some of those disappeared with the simplification of webhooks, but I would like to eliminate this as a possible underlying cause.

this.onTurn( async ( context, next ) => {
      const serviceUrl = "https://facebook.botframework.com";
      if ( context.activity.channelId === 'facebook' ) {
        MicrosoftAppCredentials.trustServiceUrl(serviceUrl)
      }
      await next();
    })

@seanbetts, do you still require assistance? The thread must be active in order to keep it open.

Hi @stevkan and @CoHealer, yes - I'm still having issues. I have just tried to implement @stevkan suggestion of adding the Facebook service url as a trusted service but I don't know how to define MicrosoftAppCredentials and get the error MicrosoftAppCredentials is not defined.
@stevkan - to your other question, I am getting individual log files for each event and it's only the trace events which are duplicated.

@seanbetts, add this to the top of you dialogBot.js file, then add the previously mentioned code.
const {
  MicrosoftAppCredentials
} = require( 'botframework-connector' );

Thanks @stevkan - I've just been testing this and I'm still getting duplicate trace logs.

@seanbetts, if you are willing to meet over Skype (or some other), can you send me an email to the address listed in my profile with some times that might work for meeting up? I'd like to see what is happening, in real time, if possible.

[@seanbetts and I are set to meet via Teams to review issue on Friday, Sept. 27 at 15:30 GMT]

@stevkan and @seanbetts did you meet and was there any conclusion?

@seanbetts and I did meet over Teams with no resolution. His bot's settings for the logger appear to be in order. The logger, with respect to Facebook, are creating what appear to be duplicate log files when trace activities populate the logs.

The customer sent the duplicate logs to review. Noticed that the entirety of each file is duplicated with the exception of the final timestamp. I believe this is just a function of the log being created, but need to verify, as the activity's timestamp is the same.

Retested using the provided code and still was unable to repro the issue with each trace saving as an individual, unique file. I did notice that the trace's timestamps, in my tests, had times prior to the activity timestamp whereas the customer's traces had timestamps posted after the activity timestamp. Going to reach out to devs for guidance.

Is it possible that you're getting two facebook messages per turn?  Maybe facebook is calling you twice for each message...

Hi @Stevenic I don’t think that’s possible. If I was then I’d be getting two responses in the chatbot.

Looking back over your code you're actually calling qnaMaker.getAnswers() multiple times.  You first call it here:
this.onMessage(async (context, next) => {
            await sendTyping(context);
            console.log('Processing a Message Activity');

>>>            const qnaResults = await this.qnaMaker.getAnswers(context);

            // Show choices if the Facebook Payload from ChannelData is not handled
            if (!await fbBot.processFacebookPayload(context, context.activity.channelData)) {

And then again within your fbBot:
                if (postback.payload === 'WHAT_IS_NEURODIVERSITY') {
                    // qnaMaker.getAnswers doesn't accept string input, so we need to adjust our turnContext
                    // to match what it expects, which is a string in Activity.Text
                    turnContext.activity.text = postback.payload;

                    // call the QnA
>>>                    const qnaResults = await qnaMaker.getAnswers(turnContext);

Each call to qnaMaker is going to generate a new trace.  Given that you call qnaMaker at the start of your onMessage handler you should pass those results through to your fbBot instead of having it call qnaMaker a second time.

Closing as resolved. If the issue persists, please feel free to reopen.

Did anyone solve this issue? Please help me to resolve this
[onTurnError]: Error: BotFrameworkAdapter.sendActivity(): missing serviceUrl.
(node:14604) UnhandledPromiseRejectionWarning: Error: missing activity.channelId
at ConversationState.getStorageKey (D:\home\site\wwwroot\node_modules\botbuilder-core\lib\conversationState.js:42:19)
at ConversationState [as storageKey] (D:\home\site\wwwroot\node_modules\botbuilder-core\lib\conversationState.js:28:30)
at ConversationState.delete (D:\home\site\wwwroot\node_modules\botbuilder-core\lib\botState.js:141:37)
at BotFrameworkAdapter.adapter.onTurnError [as turnError] (D:\home\site\wwwroot\index.js:150:35)
at middleware.run.then (D:\home\site\wwwroot\node_modules\botbuilder-core\lib\botAdapter.js:87:26)
at process._tickCallback (internal/process/next_tick.js:68:7)
(node:14604) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 6)


Edit setup for al2023 to use nodeadm

Description of changes:
Here's the beef of what changed:

lots of nodeadm apis were trimmed, starting out with a leaner set of definite parameters.
nodeadm boot process was broken into 2 phases/services: (nodeadm-config, nodeadm-run). the config service runs before cloud-init, where the run serice goes after cloud-final. This way users can utilize cloud-init scripts to interact with the nodeadm established foundations
the runtime directory of al2023 templates is now modeled after the filesystem, which gets copied onto the node during the build

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

Testing Done

tested building and running al2023 nodes on sonobouy. failures here and there but functional

Can I ask if there is a reason to push to do this sooner rather than later?
AL 2023 is still not ready for EKS. They (AWS) are working on it and the first AMI’s should be available in the next few months. But we will also have to test this fully, and ensure all of our batteries work correctly and implement hardening and the agents for Qualys, etc.
Just wondering what AL 2023 provides that AL2 does not.
Don Laidlaw | Sr. Master Principal Architect | Infor
cell:<PHONE_NUMBER>tel:902-401-6771 | @.***

From: Nick Baker @.>
Sent: Friday, January 12, 2024 13:57
To: awslabs/amazon-eks-ami @.>
Cc: Subscribed @.***>
Subject: Re: [awslabs/amazon-eks-ami] Edit setup for al2023 to use nodeadm (PR #1566)
Sent by an external sender.  Please be cautious about clicking on links and opening attachments.
@ndbaker1 commented on this pull request.

In nodeadm/internal/feature-gates/feature-gates.gohttps://github.com/awslabs/amazon-eks-ami/pull/1566#discussion_r1450761730:

@@ -36,14 +33,14 @@ func DefaultFalse(featureGate FeatureGate, featureGates map[FeatureGate]bool) bo

// Discovers all cluster details using a describe call to the eks endpoint and
// updates the value of the config's ClusterDetails in-place
-func PopulateClusterDetails(cfg *api.NodeConfig) error {
+func PopulateClusterDetails(clusterName string, cfg *api.NodeConfig) error {
we don't want the featuregates package to turn into a junk drawer of all the impl details of each feature gate
+1
ill work on breaking this up and finding a better home
—
Reply to this email directly, view it on GitHubhttps://github.com/awslabs/amazon-eks-ami/pull/1566#discussion_r1450761730, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AAA6QAN7MICWUDERTE3AELLYOF2PDAVCNFSM6AAAAABBXMRFDOVHI2DSMVQWIX3LMV43YUDVNRWFEZLROVSXG5CSMV3GSZLXHMYTQMJYG43TEMBVHA.
You are receiving this because you are subscribed to this thread.Message ID: @.***>

@dlaidlaw did you intend to post this here?

/ci


KAFKA-4200: Fix throttle argument in kafka-reassign-partitions.sh

Simple jira which alters two things:

kafka-reassign-partitions --verify prints Throttle was removed regardless of whether a throttle was applied. It should only print this if the value was actually changed.

--verify should exception if the —throttle argument. (check generate too)

To test this I extracted all validation logic into a separate method and added a test which covers the majority of combinations. The validation logic was retained as is, other than implementing (2) and adding validation to the --broker-list option which you can currently apply to any of hte main actions (where it is ignored). Requirement 1 was tested manually (as it's just println).
Testing:

Build passes locally.
System test reassign_partitions_test.py also passes.

Build failure was a timeout in KStreamAggregationIntegrationTest which I don't think is related. Rerunning

Thanks for the patch. LGTM. Just a couple of minor comments.

Thanks for the PR. I'll merge it as Jun has reviewed it and you have addressed the minor comments.

Comments all addressed.


[BUG]:Error: browserType.connect: WebSocket error: wss://westeurope.api.playwright.microsoft.com/api/authorize/connectSession 401 Unauthorized

Describe the bug
Since yesterday we've having this error with EVERY spec file we run:
Error: browserType.connect: WebSocket error: wss://westeurope.api.playwright.microsoft.com/api/authorize/connectSession 401 Unauthorized
Call log:

 wss://westeurope.api.playwright.microsoft.com/api/authorize/connectSession
86ea1997-8795-42e1-9067-41b045914491
 wss://westeurope.api.playwright.microsoft.com/api/authorize/connectSession 401 Unauthorized
 wss://westeurope.api.playwright.microsoft.com/api/authorize/connectSession error WebSocket was closed before the connection was established
 wss://westeurope.api.playwright.microsoft.com/api/authorize/connectSession WebSocket was closed before the connection was established
 wss://westeurope.api.playwright.microsoft.com/api/authorize/connectSession code=1006 reason=

To Reproduce
run any playwright test with vscode
Expected behavior
not having this "generic" error
Screenshots

Setup information (please complete the following information):

Browser on which tests are executed (if applicable): Chrome
Playwright Version: 14.1
Client machine OS: WIndows 11

AB#1952828

Hi @AlanCodega
Thanks for reaching out. This error could be because the Access Token you were using to authenticate with the service is expired or not set for this run.
Could you check if the token is active and create a new token if it's expired? Here's the documentation: https://learn.microsoft.com/en-us/azure/playwright-testing/how-to-manage-access-tokens

Hi @AlanCodega Thanks for reaching out. This error could be because the Access Token you were using to authenticate with the service is expired or not set for this run. Could you check if the token is active and create a new token if it's expired? Here's the documentation: https://learn.microsoft.com/en-us/azure/playwright-testing/how-to-manage-access-tokens

Hi @vvs11 ,
many thanks for your reply.
it's the 1st thing I thought.
I've re-create the token following this guide:

But still have the same issue, even if I want to run locally:

HI @AlanCodega We checked our telemetry and it shows that token you are using is expired, one possibility is though you have generated new token but you havent updated it your system to pick new token value.  Can you please check your environment variable once. You can actually check the token validatity via jwt.io , please confirm after this.

HI @AlanCodega We checked our telemetry and it shows that token you are using is expired, one possibility is though you have generated new token but you havent updated it your system to pick new token value. Can you please check your environment variable once. You can actually check the token validatity via jwt.io , please confirm after this.

Hi @puagarwa,
Many thanks for your reply.
i found the issue, and you have reason.
I updated the token following the guide using powershell commands, but we had an .env fine in our vs code.
Once I've updated the token here, everything was run as before.
Many thanks for your help.


Add xcode-install to the fastlane family

Closing this for now, as we want to keep the tool as a standalone repo for now https://github.com/krausefx/xcode-install 👍
Thanks for handing this over @neonichu cc @neonacho


Handle deleted accounts

This PQ broke the component, it isn't being displayed as all anymore now.

Seems fine to me. :thinking:

Can you try it with the time set to the moment I posted the above comment?

This PQ broke the component, it isn't being displayed at all anymore now.

https://github.com/grammyjs/website/pull/979


Tray Notification Location Linux Mint

The notification in the top right corner of the screen Linux mint that appears when lever you get a notification. I've gone through dozens of forums, I believe this to be specifically a runelite issue. I want to change the location of the notification to the bottom right corner, but can't. Please allow this.

We don't specify that anywhere in our notifier; we simply call notify-send with a message, icon, urgency, and timeout.
Sounds like you would need to install some kind of third-party patch to the utility (see this AskUbuntu question and answer, for instance) to do what you're asking.


why this wav gets compressed 4x more by 7zip than by WavPack? (question)

Hi, I recently noticed that when you compress this wav file with 7zip, it gets much smaller than with WavPack, more than 4x
Can someone explain this behaviour?
Thanks for any help :)
This is the file:
44-AudioTrack-44.zip
og wave:   65,10 MB
WavPack:   39,20 MB
7zip:            8,14 MB

There is something artificial about that file that makes it compress much better with general-purpose compressors than with audio compressors. I verified that even my two general-purpose compressors do much better than WavPack!
My first guess was that it simply exactly repeated over each click, which a general-purpose compressor can take advantage of whereas an audio compressors generally would not (because real sampled audio never repeats exactly). But that wasn't it. And looking at the hex data and several other experiments also revealed nothing. I also tried the float32 optimization that I developed a while back (and dropped because it didn't achieve anything will real files in the wild), and got nothing.
So I gave up trying to figure out what specifically is different about this file. But as a final experiment I added -100 dB white noise to the file (which is way below its noise floor) and suddenly WavPack compressed it better than general-purpose compressors. So it is something artificial about the data, I just don't know exactly what.

Wow thats a deep dive, thank you for that info. I was very surprised as I saw that, and thought maybe it's worth to report it.

If it is any "comfort", then OptimFROG doesn't leap to well with this one either, it performs kinda in the ballpark you would expect compared to WavPack alone. The heaviest MP4ALS compressions do save another few megabytes, down to 30. Which is just around the level of NTFS "ordinary" compression: 30.8.
compact /c /exe:lzx gets it down to 14. (15 if I split in 1sec chunks.)

Alright, I got curious again. The redundancy in this file is that while it purports to be 32-bit float audio, there are only 56814 unique values. The most common value covers over 3% of the samples and half of the samples are covered with only 25 values. So yeah, that’s why it’s super compressible and this is exactly the kind of thing that general-purpose compressors find. And adding just a tiny amount of noise completely destroys that artificial characteristic.

Awesome job!


Deleted read-torrent

TODO was not to use read-torrent but it's now using https://github.com/feross/simple-get instead.

@deamme do you know if simple-get inflates gzipped http requests? other than that this is LGTM

I know the answer – yep. simple-peer handles gzip or deflate responses from the server :+1:

@feross almost did the same typo you just did when writing simple-get as well

@deamme LGTM - could you update this PR so it merges against the master branch?

@mafintosh lol

@mafintosh is this not already fixed with parse-torrent?

@deamme lol yea you're right.


Recursive routing: parent routes should not receive child route params

createTest('Nested routes with forward recursion: handlers for higher-level routes should not receive child params', {
  '/foo': {
    on: function () {
      shared.fired.push(Array.prototype.slice.call(arguments));
    },
    '/:bar': {
      on: function () {
        shared.fired.push(Array.prototype.slice.call(arguments));
      }
    }
  }
}, {
  recurse: 'forward'
}, function () {
  shared.fired = [];
  this.navigate('/foo/bar', function () {
    deepEqual(shared.fired, [[], ['bar']]);
    this.finish();
  });
});

We get [['bar'], ['bar']] instead of [[], ['bar']].
This is especially problematic for async routing, since you don't know where to put the next param: there could be any number of extra params before next, due to different children intercepting the route.

Just ran into this myself. Should be a note in the documentation for async routing when recurse is not false. Corner case, but will save the next person : )
When using URL Matching or URL Parameters, *and* async routing, *and* any type of route recursion, note that all the methods in the recursive chain will have all the parameters of the final, matched route. In this case, one could find the async callback `next` for any `on`/`before`/`after`/`once` function like this `var next = Array.prototype.slice.call(arguments).pop()`.


Use EDoc format internally

Right now we use a custom internal state based heavily on lfe_doc_v1 records. It might be worthwhile to adopt the EDoc record format.
Related:

OLP releases (https://github.com/lfe/olp/issues/1)
Generate docs from Erlang source (#31)

I'm making some progress on this locally.  I think I'll split the lodox project into two apps:

lodox (the rebar3 plugin)
ldoc (the lfe_docs_v1 parser and EDoc generator)

@oubiwann, @rvirding: Do you think I should make ldoc a separate repo, or just keep it here under apps/? Possible motivation for the former could be if a user might want to manipulate EDoc records generated form LFE source but not use Lodox. I'm leaning toward apps/, for now anyway. If you vote separate repo, could you create lfex/ldoc and give me admin privileges?

It might also be good to split out the forthcoming markdown, JSON and text writers into their own repos. Those belong in the lfe-rebar3 org, I think. I figure lodox-{{format}} is a good naming scheme, if we decide to do that.

Hmm, on second thought, we probably won't need a rebar3 plugin anymore, since I'm writing an EDoc doclet module in ldoc...


Gen 7 Egg Accept/Reject Calculation

Should probably include the secondary egg view to focus on accept/reject calculations.
https://gyazo.com/9105309682353826ef9ebc85b7a6430e
Also should consider using Dijkstra's formula to calculate shortest path of accept/rejects.
https://www.reddit.com/r/pokemontrades/comments/61qhe6/daily_discussion_question_thread_for_27_march_2017/dfgj9uo/

The formula looks like it could work well for this.  Here's a node version - https://www.npmjs.com/package/node-dijkstra
I don't think we'll need a new view for this - we can just add a new setting box.

I talked to fish about this but not completely sure if this is the best thing to implement (Dijkstra's Algorithm). If it is implemented here, I'd highly suggest using a checkbox for whether the user wants it cause I think it'd have a pretty long runtime. Doesn't hurt to try though :p

Yeah a checkbox was the original idea I had in mind. User could choose between default or fastest path.

It could also come as a button AFTER the original search (for example, Calculate Shortest Path). This would probably make the most sense since you would need all the data from the entire search anyways to implement a shortest paths algorithm.

I really do like the Dijkstra method, however this does require the original data first, so a checkbox makes sense.
For the user it makes sense as well - they get to see the results before deciding which egg to get the shortest path for.
Having the button be usable after the search I like, however I think it should only be disabled until a search is performed, not invisible - users know the option is there in that way.
What are everyone's thoughts on a disabled button vs. invisible button, as well as if we should use Dijkstra's Algorithm or a different method?

Disabled button sounds best to me, otherwise it may be easily overlooked.
I was reading law's method thats described in fish's reddit post but I'm not thoroughly convinced, at least not the last 10 accepts. I don't think that would affect the # of accepts/rejects enough to make it worth it. I would say dijkstra's, especially if its already available as a package. We might need to do some testing though - I like the idea of using the algorithm for the last X number of accepts. We probably need to find the sweet point that hits a decent runtime but also actually saves time. (honestly, I'm thinking more of its application to shiny TSV RNGs, I think dijkstra's will run fine for normal breedables)


Fix Drone setup

Old Drone setup did not have support for testing with headless Chrome. I know it is a bit silly, since there are no tests for this repository, but even some implicit test (to make sure assert are working properly) fails.
Another possibility is to outright disable all tests in the Drone setup, but maybe not a good idea for future proofing.

I accidentally based this PR of another branch with a lot of changes. This branch will be merged only if changes to the other PR are approved. Rebase failed to do anything useful.


Implement dark theme for sniffy

Might be usefull for the demo to look consistent with the site

Not that useless as it seems

Implemented in https://github.com/sniffy/sniffy-ui/pull/7


Comply to validator.prestashop.com rules

This is a PR to comply with Modules validation standards (validator.prestashop.com).
Before the PR, there uses to be 77 errors, 8 warnings and 9 security issues.
The PR lowers these numbers to 10 errors and 5 warnings. I did not fix it all because the last errors/warnings do not seem relevant to me.
Each commit fixes a specific set of rules.

@eternoendless @Quetzacoalt91 ?

Thank you @matks

Comply to rules / Convert arrays to short syntax aren't compatible. I hope this module is not used on PS 1.6.


create or replace resources on REAPPLY, to ensure no "downtime"

otherwise the few ms between "drop" and "create" will lead to outages if used in prod
also - the fact that we can't rollback means that if there is a syntax error, we would have dropped and never reapplied (hopefully users would have tested it before, but still would be better to not even have the risk)
e.g., instead of DROP, CREATE
REPLACE CREATEw/CREATE IF NOT EXISTS``

specifically here https://github.com/uladkasach/schema-control/blob/079e6455c06d321d44dfc16ed87e95c976312129/src/logic/plan/applyPlan/applyPlanForResource.ts#L18


updated documentation for tensorflow lite micro-speech example on NXP…

…-k66f board. Documentation now explains which versions of Python to use with mbed-cli (step 5). It omits an erroneous step that would cause the compilation stage to fail (previously step 6) by changing compiler flags from c++14 to c++11 for Mbed OS code which resulted in issues that prevented the example from running as code uses things like std::enable_if_t which is a c++14 feature used by Mbed OS. Also, added an extra step explaining DPALink if not already enabled on board.

@googlebot I signed it!


Bool literals not downcasted

Using integer literals as boolean values causes errors because they are not truncated properly to boolean values

Fixed boolean value truncation


Introduce context for decoding

Decoding context
A context contains polynomials that are computed once, for a given set of indices of received fragments fragments_ids = {x_1, x_2, .., x_k}.
These polynomials will be served to decode original data given k received fragments.

Following polynomials are initialized by Context and does not change during the decoding:

A := (x - x_1)(x - x_2)..(x-x_k)
inv_A_i := 1 / (x_i * A_i(x_i))

Following polynomials are allocated by Context and will be used to docomputations during the decoding:

N_p stores sum_i{n_i * x^z_i}
N_p_ifft stores output of FFT(N_p)
S stores decoded symbols

Refactor decoding into two steps

Initialize context for given received fragments index
Perform decoding using the computed context on received fragments

@slaperche-scality : the code is updated. Thanks for your reviews :)

I squashed commits only


Appstudio update test-component-pac-rpvx

Pipelines as Code configuration proposal

Pipelines as Code CI/test-component-pac-rpvx-on-pull-request has failed.

StatusDurationName

✅ Succeeded
33 seconds
init

✅ Succeeded
35 seconds
clone-repository

✅ Succeeded
1 minute
build-container

❌ Failed
39 seconds
clair-scan

✅ Succeeded
1 minute
clamav-scan

✅ Succeeded
41 seconds
deprecated-base-image-check

✅ Succeeded
40 seconds
sanity-inspect-image

✅ Succeeded
22 seconds
sbom-json-check

✅ Succeeded
11 seconds
show-summary

Failure reasontask clair-scan has the status "TaskRunImagePullFailed":
The step "get-vulnerabilities" in TaskRun "test-component-pac-rpvx-on-pull-request-qmtrd-clair-scan" failed to pull the image "". The pod errored with the message: "Back-off pulling image "quay.io/redhat-appstudio/clair-in-ci:latest"."


Watchdog

setup/disable/feed implementation with new driver needs to be done
Suspend, resume with handling for pinmux states changes, clock disablement or switch low power clock handling

There is initial work pushed from TI: https://github.com/msp-ti/zephyr/commit/cd47617390652a91fe6388d21a53d9887bad9048

Tested with west build -p -b lp_mspm0g3507 -s samples/drivers/watchdog/


mem-ruby: Writeback CHI UD_RU line at local evict

In Ruby CHI protocol UD_RU state means the line is in UD state in the local cache and the upstream may have it in UD or UC state. In the previous implementation UD_RU line was just dropped without WriteBack which can cause loss of dirty data when the upstream has it in UC state.
This commit fixes it by performing WriteBack when evicting UD_RU line.

Hi @tiagormk, could you take a look at this PR? Thank you.

@tiagormk , Thank you very much for the comments. My understanding on UD_RU state was wrong.
Btw, here's the sequence that led to the loss of dirty data. I apologize that I have lost the full traces I used for debugging couple of months ago, and writing this based on my memory.
Configs:

L2 caches: (roguhly inclusive to L1 without back invalidation)

dealloc_on_*=false
dealloc_backinv_*=false

L3 caches: (rouhgly exclusive without back invalidation)

alloc_on_readshared=true
alloc_on_readunique=false
dealloc_on_shared=false
dealloc_on_unique=true
dealloc_backinv_*=false
is_HN=false

Last-level cache: (same clusivity as L3)

is_HN=true

allow_SD=true for all caches
fwd_unique_on_readshared=false for all caches

Sequence:

L1 sends ReadUnique then becomes UD. L2 is UC_RU. L3 and LLC are RU.
L1 evicts the line to L2 by WriteBack_UD_PD. L2 becomes UD.
L2 evicts the line to L3 using WriteBackFull_UD_PD. L3 becomes UD.
L1 reads the line with ReadShared. L2 reads the line with ReadShared. L2 becomes SC_RSC. L3 becomes UD_RSC.
L3 evicts the line to LLC.

At this time, Initiate_Replacement_WB sends WriteClean because L3 doesn't back-invalidate and still has sharer. https://github.com/gem5/gem5/blob/d1fca18eb37d53b1e6fcb7802b35f4be87fd81ec/src/mem/ruby/protocol/chi/CHI-cache-actions.sm#L1380C1-L1391C4
The cache line in L3 eventually goes Invalid. https://github.com/gem5/gem5/blob/d1fca18eb37d53b1e6fcb7802b35f4be87fd81ec/src/mem/ruby/protocol/chi/CHI-cache-transitions.sm#L765
L3 becomes RUSC and LLC becomes UD_RU.

UD_RU line is just dropped at LLC.

Although my memory on the sequence is correct, I should've changed the other part to keep the meaning of UD_RU. It'll be grategul if you give any advice on that.

Thanks for input @jjuninho. I think what you said make sense.  The solution for this is a bit tricky though. If we maintain the meaning of UD_RU then the Writeback in your patch will fail because the data your are writing is maked as invalid.
IMO it makes more sense to change Send_CompData (https://github.com/gem5/gem5/blob/stable/src/mem/ruby/protocol/chi/CHI-cache-actions.sm#L2568) to always propagate the dirty state in those conditions you described. E.g.:
Change:
// if the config allows (or not caching the data) and line has no sharers
bool snd_unique_on_rs := (fwd_unique_on_readshared || tbe.dataToBeInvalid)
&& tbe.dataUnique && tbe.dir_sharers.isEmpty();
// if the request type allows and we won't be caching the data
bool snd_dirty_on_rs := is_rd_shared && !is_rd_nsd && tbe.dataToBeInvalid;
To:
// check if the request type allows sending SD
bool snd_dirty_on_rs := is_rd_shared && !is_rd_nsd;
// send UC/UD if line has no sharers and config allows, or not caching the data,
// or we'd send SD but can't
bool snd_unique_on_rs := (fwd_unique_on_readshared || tbe.dataToBeInvalid || (tbe.dataDirty && !snd_dirty_on_rs))
&& tbe.dataUnique && tbe.dir_sharers.isEmpty();

Hi @jjuninho,
None of the commits in this pull request contains a Change-ID, which we require for any changes made to gem5.   Thank you.

@ivanaamit , Thank you for the guide. I'm aware of that this pull request is not satisfying the prerequisites for merge. I'm working behind the heavy compary firewalls and haven't found the way to make the pre-commit work. I'll apply your guide out side of my office and push the commits again.


Any plans to support Cockroach?

Hey team,
Are there any plans for Bun to support CockroachDB, its gaining major traction lately and it would be awesome to use Bun as the query builder/ORM?
Thanks in advance :))

You can use a Postgres ORM if you want to use CockroachDB

Yes, use pgdialect with CockroachDB - https://bun.uptrace.dev/postgres/ . If there are incompatibilities, we can create a separate dialect for CockroachDB.


checkHtml: get the existing content interface Mammoth styles supported

Currently generating a syntax error

Was a problem with the underline definition.  Perhaps new versino of Mammoth doesn't like it.


mpb.New().SetWidth and bar.Completed are undefined

I am receiving compilation errors with the latest revision:
src/github.com/UnnoTed/fileb0x/updater/updater.go:225: mpb.New().SetWidth undefined (type *mpb.Progress has no field or method SetWidth)
src/github.com/UnnoTed/fileb0x/updater/updater.go:333: bar.Completed undefined (type *mpb.Bar has no field or method Completed)

Fixed, run go get -u github.com/UnnoTed/fileb0x.


New cell after preformatted.

Enter and Shift+Enter both will create a new line inside a preformatted cell.
Cant figure out howt to create new cell after preformatted.
Thanks.

Hold down Ctrl and select the paragraph tool from the toolbox.

Oh wow, thanks a lot!
That was a waste of half hour but no matter.
Again thanks for your brilliant work.


[Request] ELI5 documentation on swapping out database connection settings.

Hey guys,
In the setup docs there is a segment on modifying database connection settings, but the documentation is pretty sparse.  I was hoping to get some help setting up a connection to a local Postgres database.
Disclaimer: We're a Ruby shop, with minimal knowledge of Java frameworks or tools.  And this is where I think we're getting a little lost.  In Genie v1 we hacked some settings in the persistence-sql.xml file.  In attempting to deploy Genie v2, we're getting stuck in the genie-jpa.xml.
In any case, if I set CATALINA_OPTS to "-Dspring.profiles.active=prod -Darchaius.deployment.applicationId=genie -Darchaius.deployment.environment=prod", then I believe the relevant block from genie-jpa.xml is this one:
    <beans profile="prod">
        <bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
            <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
            <property name="url" value="jdbc:mysql://<IP_ADDRESS>/genie"/>
            <property name="username" value="root"/>
            <property name="password" value=""/>
            <property name="minIdle" value="5"/>
            <property name="maxIdle" value="20"/>
            <property name="maxTotal" value="40"/>
            <property name="validationQuery" value="select 0;"/>
            <property name="testOnBorrow" value="true"/>
            <property name="testOnCreate" value="true"/>
            <property name="testWhileIdle" value="true"/>
            <property name="testOnReturn" value="true"/>
            <property name="minEvictableIdleTimeMillis" value="60000"/>
            <property name="timeBetweenEvictionRunsMillis" value="10000"/>
        </bean>
    </beans>

Changing the username and password seems fairly straightforward.  But I could really use an example on how to swap out these first few lines in order to properly load a PostgreSQL driver in Beans:
        <bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
            <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
            <property name="url" value="jdbc:mysql://<IP_ADDRESS>/genie"/>

We considered just going with MySQL, but everything else we run here is Postgres.  If we can easily sub in connection drivers, that would be the ideal solution.
I'm not sure how many other non-Java teams are attempting to build or deploy Genie, but I think throwing an extra example into the docs would be great for anybody else facing the same issue.
~J

@Joseph-R I believe we got you through this in the google group right?
For 3.0 we're planning on having a lot more documentation. Also since it leverages Spring Boot documentation should be easy to find.
You might also find #196 of interest to you. We're not Postgres experts or DBA's by any means so any feedback/testing help on the scripts would be appreciated.

Part of #154

Covered in Reference Documentation available on website after every build.


Fix #271

This fixes #271

We should probably get this merged.

@lnaden: Could you help with enabling osx tests here?

@pgrinaway Looks like tests are re-running. Can you merge when done?

I'm not sure we ever correctly enabled the osx tests. Those might have to be fixed separately. There were no osx tests previously, which is how this issue cropped up.

Yep, I just wanted to see how the tests go before merging.

I'm not sure we ever correctly enabled the osx tests. Those might have to be fixed separately.

Yeah, I think you're right.

@jchodera  the openmoltools tests are failing on travis (see 1326.2 and 1326.3) and when I run them locally (after merging this commit with master)


chore(init): Remove connect workflow and create factory init method

:tada: This PR is included in version 1.0.0 :tada:
The release is available on:

npm package (@latest dist-tag)
GitHub release

Your semantic-release bot :package::rocket:


Dataset used

Hello,
Thanks for this amazing contribution !
Is it possible to have some informations about the dataset used, especially for the 'autoencoder1d-AT-v1' model ?
It would be very nice to know what dataset was used for each model, are they from the audio-data-pytorch repo ?
Thank you very much

Could you use it on custom data? @ggenesum  ?


FIX get_table_id should correctly handle quoted schema.tablename

Resolves #276

This PR is a duplicate of #283, following IT-support's advice to create a new PR with Travis builds (which presumably IT-support has fixed).

According to IT-support (who emailed Travis CI's support), Travis CI doesn't yet support builds for PRs marked as "draft" (a new feature on GitHub). Closing this PR in favor of #285.