export function mergeRelevantTextDocuments()

in server/aws-lsp-codewhisperer/src/language-server/agenticChat/context/contextUtils.ts [76:125]


export function mergeRelevantTextDocuments(documents: RelevantTextDocumentAddition[]): FileList {
    if (documents.length === 0) {
        return { filePaths: [], details: {} }
    }

    const details: Record<string, FileDetails> = {}

    Object.entries(
        documents.reduce<Record<string, { first: number; second: number }[]>>((acc, doc) => {
            if (!doc.relativeFilePath || doc.startLine === undefined || doc.endLine === undefined) {
                return acc // Skip invalid documents
            }

            if (!acc[doc.relativeFilePath]) {
                acc[doc.relativeFilePath] = []
            }
            acc[doc.relativeFilePath].push({ first: doc.startLine, second: doc.endLine })
            return acc
        }, {})
    ).forEach(([relativeFilePath, ranges]) => {
        // Sort by startLine
        const sortedRanges = ranges.sort((a, b) => a.first - b.first)

        const mergedRanges: { first: number; second: number }[] = []
        for (const { first, second } of sortedRanges) {
            if (mergedRanges.length === 0 || mergedRanges[mergedRanges.length - 1].second < first - 1) {
                // If no overlap, add new range
                mergedRanges.push({ first, second })
            } else {
                // Merge overlapping or consecutive ranges
                mergedRanges[mergedRanges.length - 1].second = Math.max(
                    mergedRanges[mergedRanges.length - 1].second,
                    second
                )
            }
        }

        const fullPath = documents.find(doc => doc.relativeFilePath === relativeFilePath)?.path
        details[relativeFilePath] = {
            fullPath: fullPath,
            description: fullPath,
            lineRanges: mergedRanges,
        }
    })

    return {
        filePaths: Object.keys(details),
        details: details,
    }
}