public async sendAIResponse()

in packages/core/src/amazonqTest/chat/controller/messenger/messenger.ts [180:336]


    public async sendAIResponse(
        response: GenerateAssistantResponseCommandOutput,
        session: Session,
        tabID: string,
        triggerID: string,
        triggerPayload: TriggerPayload,
        fileName: string,
        fileInWorkspace: boolean
    ) {
        let message = ''
        let messageId = response.$metadata.requestId ?? ''
        let codeReference: CodeReference[] = []

        if (response.generateAssistantResponseResponse === undefined) {
            throw new ToolkitError(
                `Empty response from Q Developer service. Request ID: ${response.$metadata.requestId}`
            )
        }

        const eventCounts = new Map<string, number>()
        waitUntil(
            async () => {
                for await (const chatEvent of response.generateAssistantResponseResponse!) {
                    for (const key of keys(chatEvent)) {
                        if ((chatEvent[key] as any) !== undefined) {
                            eventCounts.set(key, (eventCounts.get(key) ?? 0) + 1)
                        }
                    }

                    if (
                        chatEvent.codeReferenceEvent?.references !== undefined &&
                        chatEvent.codeReferenceEvent.references.length > 0
                    ) {
                        codeReference = [
                            ...codeReference,
                            ...chatEvent.codeReferenceEvent.references.map((reference) => ({
                                ...reference,
                                recommendationContentSpan: {
                                    start: reference.recommendationContentSpan?.start ?? 0,
                                    end: reference.recommendationContentSpan?.end ?? 0,
                                },
                                information: `Reference code under **${reference.licenseName}** license from repository \`${reference.repository}\``,
                            })),
                        ]
                    }
                    if (testGenState.isCancelling()) {
                        return true
                    }
                    if (
                        chatEvent.assistantResponseEvent?.content !== undefined &&
                        chatEvent.assistantResponseEvent.content.length > 0
                    ) {
                        message += chatEvent.assistantResponseEvent.content
                        this.dispatcher.sendBuildProgressMessage(
                            new BuildProgressMessage({
                                tabID,
                                messageType: 'answer-part',
                                codeGenerationId: '',
                                message,
                                canBeVoted: false,
                                messageId,
                                followUps: undefined,
                                fileList: undefined,
                            })
                        )
                    }
                }
                return true
            },
            { timeout: 60000, truthy: true }
        )
            .catch((error: any) => {
                let errorMessage = 'Error reading chat stream.'
                let statusCode = undefined
                let requestID = undefined
                if (error instanceof CodeWhispererStreamingServiceException) {
                    errorMessage = error.message
                    statusCode = getHttpStatusCode(error) ?? 0
                    requestID = getRequestId(error)
                }
                let message = 'This error is reported to the team automatically. Please try sending your message again.'
                if (errorMessage !== undefined) {
                    message += `\n\nDetails: ${errorMessage}`
                }

                if (statusCode !== undefined) {
                    message += `\n\nStatus Code: ${statusCode}`
                }

                if (requestID !== undefined) {
                    messageId = requestID
                    message += `\n\nRequest ID: ${requestID}`
                }
                this.sendMessage(message.trim(), tabID, 'answer')
            })
            .finally(async () => {
                if (testGenState.isCancelling()) {
                    this.sendMessage(CodeWhispererConstants.unitTestGenerationCancelMessage, tabID, 'answer')
                    TelemetryHelper.instance.sendTestGenerationToolkitEvent(
                        session,
                        false,
                        fileInWorkspace,
                        'Cancelled',
                        messageId,
                        performance.now() - session.testGenerationStartTime,
                        getTelemetryReasonDesc(
                            `TestGenCancelled: ${CodeWhispererConstants.unitTestGenerationCancelMessage}`
                        ),
                        undefined,
                        undefined,
                        undefined,
                        undefined,
                        undefined,
                        undefined,
                        undefined,
                        undefined,
                        undefined,
                        undefined,
                        'TestGenCancelled',
                        'CANCELLED'
                    )
                    this.dispatcher.sendUpdatePromptProgress(
                        new UpdatePromptProgressMessage(tabID, cancellingProgressField)
                    )
                    await sleep(500)
                } else {
                    TelemetryHelper.instance.sendTestGenerationToolkitEvent(
                        session,
                        false,
                        fileInWorkspace,
                        'Succeeded',
                        messageId,
                        performance.now() - session.testGenerationStartTime,
                        undefined,
                        undefined,
                        undefined,
                        undefined,
                        undefined,
                        undefined,
                        undefined,
                        undefined,
                        undefined,
                        undefined,
                        undefined,
                        undefined,
                        'ACCEPTED'
                    )
                    this.dispatcher.sendUpdatePromptProgress(
                        new UpdatePromptProgressMessage(tabID, testGenCompletedField)
                    )
                    await sleep(500)
                }
                testGenState.setToNotStarted()
                // eslint-disable-next-line unicorn/no-null
                this.dispatcher.sendUpdatePromptProgress(new UpdatePromptProgressMessage(tabID, null))
            })
    }