fun shouldTriggerClassifier()

in plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/service/CodeWhispererAutoTriggerService.kt [124:264]


    fun shouldTriggerClassifier(
        editor: Editor,
        automatedTriggerType: CodewhispererAutomatedTriggerType = CodewhispererAutomatedTriggerType.Classifier, // TODO: need this?
    ): ClassifierResult {
        val caretContext = runReadAction { CodeWhispererEditorUtil.extractCaretContext(editor) }
        val language = runReadAction {
            FileDocumentManager.getInstance().getFile(editor.document)?.programmingLanguage()
        } ?: CodeWhispererUnknownLanguage.INSTANCE
        val caretPosition = runReadAction { CodeWhispererEditorUtil.getCaretPosition(editor) }

        val leftContextLines = caretContext.leftFileContext.split(Regex("\r?\n"))
        val leftContextLength = caretContext.leftFileContext.length
        val leftContextAtCurrentLine = if (leftContextLines.size - 1 >= 0) leftContextLines[leftContextLines.size - 1] else ""
        var keyword = ""
        val lastToken = leftContextAtCurrentLine.trim().split(" ").let { tokens ->
            if (tokens.size - 1 >= 0) tokens[tokens.size - 1] else ""
        }
        if (lastToken.length > 1) keyword = lastToken

        val lengthOfLeftCurrent = leftContextAtCurrentLine.length
        val lengthOfLeftPrev = if (leftContextLines.size - 2 >= 0) {
            leftContextLines[leftContextLines.size - 2].length.toDouble()
        } else {
            0.0
        }

        val rightContext = caretContext.rightFileContext
        val lengthOfRight = rightContext.trim().length

        val triggerTypeCoefficient = CodeWhispererClassifierConstants.triggerTypeCoefficientMap[automatedTriggerType] ?: 0.0

        val osCoefficient: Double = if (SystemInfo.isMac) {
            CodeWhispererClassifierConstants.osMap["Mac OS X"] ?: 0.0
        } else if (SystemInfo.isWindows) {
            val osVersion = SystemInfo.OS_VERSION
            if (osVersion.contains("11", true) || osVersion.contains("10", true)) {
                CodeWhispererClassifierConstants.osMap["Windows 10"]
            } else {
                CodeWhispererClassifierConstants.osMap["Windows"]
            }
        } else {
            0.0
        } ?: 0.0

        val lastCharCoefficient = if (leftContextAtCurrentLine.length - 1 >= 0) {
            CodeWhispererClassifierConstants.coefficientsMap[leftContextAtCurrentLine[leftContextAtCurrentLine.length - 1].toString()] ?: 0.0
        } else {
            0.0
        }

        val keywordCoefficient = CodeWhispererClassifierConstants.coefficientsMap[keyword] ?: 0.0
        val averageLanguageCoefficient = CodeWhispererClassifierConstants.languageMap.values.average()
        val languageCoefficient = CodeWhispererClassifierConstants.languageMap[language] ?: averageLanguageCoefficient
        val ideCoefficient = 0.0

        var previousOneAccept: Double = 0.0
        var previousOneReject: Double = 0.0
        var previousOneOther: Double = 0.0
        val previousOneDecision =
            if (CodeWhispererFeatureConfigService.getInstance().getNewAutoTriggerUX()) {
                CodeWhispererTelemetryServiceNew.getInstance().previousUserTriggerDecision
            } else {
                CodeWhispererTelemetryService.getInstance().previousUserTriggerDecision
            }
        if (previousOneDecision == null) {
            previousOneAccept = 0.0
            previousOneReject = 0.0
            previousOneOther = 0.0
        } else {
            previousOneAccept =
                if (previousOneDecision == CodewhispererPreviousSuggestionState.Accept) {
                    CodeWhispererClassifierConstants.prevDecisionAcceptCoefficient
                } else {
                    0.0
                }
            previousOneReject =
                if (previousOneDecision == CodewhispererPreviousSuggestionState.Reject) {
                    CodeWhispererClassifierConstants.prevDecisionRejectCoefficient
                } else {
                    0.0
                }
            previousOneOther =
                if (
                    previousOneDecision != CodewhispererPreviousSuggestionState.Accept &&
                    previousOneDecision != CodewhispererPreviousSuggestionState.Reject
                ) {
                    CodeWhispererClassifierConstants.prevDecisionOtherCoefficient
                } else {
                    0.0
                }
        }

        var leftContextLengthCoefficient: Double = 0.0

        leftContextLengthCoefficient = when (leftContextLength) {
            in 0..4 -> CodeWhispererClassifierConstants.lengthLeft0To5
            in 5..9 -> CodeWhispererClassifierConstants.lengthLeft5To10
            in 10..19 -> CodeWhispererClassifierConstants.lengthLeft10To20
            in 20..29 -> CodeWhispererClassifierConstants.lengthLeft20To30
            in 30..39 -> CodeWhispererClassifierConstants.lengthLeft30To40
            in 40..49 -> CodeWhispererClassifierConstants.lengthLeft40To50
            else -> 0.0
        }

        val normalizedLengthOfRight = CodeWhispererClassifierConstants.lengthofRightCoefficient * VariableTypeNeedNormalize.LenRight.normalize(
            lengthOfRight.toDouble()
        )

        val normalizedLengthOfLeftCurrent = CodeWhispererClassifierConstants.lengthOfLeftCurrentCoefficient * VariableTypeNeedNormalize.LenLeftCur.normalize(
            lengthOfLeftCurrent.toDouble()
        )

        val normalizedLengthOfPrev = CodeWhispererClassifierConstants.lengthOfLeftPrevCoefficient * VariableTypeNeedNormalize.LenLeftPrev.normalize(
            lengthOfLeftPrev
        )

        val normalizedLineNum = CodeWhispererClassifierConstants.lineNumCoefficient * VariableTypeNeedNormalize.LineNum.normalize(caretPosition.line.toDouble())

        val intercept = CodeWhispererClassifierConstants.intercept

        val resultBeforeSigmoid =
            normalizedLengthOfRight +
                normalizedLengthOfLeftCurrent +
                normalizedLengthOfPrev +
                normalizedLineNum +
                languageCoefficient +
                osCoefficient +
                triggerTypeCoefficient +
                lastCharCoefficient +
                keywordCoefficient +
                ideCoefficient +
                previousOneAccept +
                previousOneReject +
                previousOneOther +
                leftContextLengthCoefficient +
                intercept

        val shouldTrigger = sigmoid(resultBeforeSigmoid) > getThreshold()

        return ClassifierResult(shouldTrigger, sigmoid(resultBeforeSigmoid))
    }