(text: string)
| 930 | * @returns Array of text chunks with preserved structure |
| 931 | */ |
| 932 | export function chunkStructuredDocs(text: string): string[] { |
| 933 | const chunks: string[] = []; |
| 934 | const lines = text.split("\n"); |
| 935 | |
| 936 | // Step 1: Extract all headers and build a header hierarchy |
| 937 | interface HeaderInfo { |
| 938 | level: number; |
| 939 | title: string; |
| 940 | lineIndex: number; |
| 941 | } |
| 942 | |
| 943 | const headers: HeaderInfo[] = []; |
| 944 | |
| 945 | lines.forEach((line, index) => { |
| 946 | const headerMatch = line.match(/^(#{1,6})\s+(.*)/); |
| 947 | if (headerMatch) { |
| 948 | headers.push({ |
| 949 | level: headerMatch[1].length, |
| 950 | title: headerMatch[2].trim(), |
| 951 | lineIndex: index, |
| 952 | }); |
| 953 | } |
| 954 | }); |
| 955 | |
| 956 | // If there's at least one header, create a chunk with the document title and description |
| 957 | if (headers.length > 0) { |
| 958 | const mainHeader = headers[0]; |
| 959 | let mainDescription = ""; |
| 960 | |
| 961 | // Collect the main description until we hit another header or a blank line followed by a list item |
| 962 | for (let i = mainHeader.lineIndex + 1; i < lines.length; i++) { |
| 963 | const line = lines[i].trim(); |
| 964 | |
| 965 | // Stop if we hit another header |
| 966 | if (line.match(/^#{1,6}\s+/)) break; |
| 967 | |
| 968 | // Stop if we hit a blank line followed by a list item |
| 969 | if ( |
| 970 | line === "" && |
| 971 | i + 1 < lines.length && |
| 972 | (lines[i + 1].trim().startsWith("- ") || |
| 973 | lines[i + 1].trim().startsWith("* ")) |
| 974 | ) |
| 975 | break; |
| 976 | |
| 977 | if (line !== "") { |
| 978 | mainDescription += mainDescription ? "\n" + line : line; |
| 979 | } |
| 980 | } |
| 981 | |
| 982 | // Create a chunk with main title and description |
| 983 | if (mainDescription) { |
| 984 | chunks.push(`# ${mainHeader.title}\n\n${mainDescription}`); |
| 985 | } |
| 986 | } |
| 987 | |
| 988 | // Find the current section header for context |
| 989 | const getCurrentHeader = (lineIndex: number): string => { |
no test coverage detected