Files
geo/server/internal/tenant/app/knowledge_chunking.go
T
root dbd7747742 feat: add knowledge markdown formatting and detail retrieval
- Implemented KnowledgeWebsiteMarkdownPrompt for formatting webpage content into Markdown.
- Added GetItemDetail method in KnowledgeHandler to retrieve knowledge item details.
- Introduced KnowledgeDetailDrawer component for displaying knowledge item details in the admin web interface.
- Created MarkdownPreview component for rendering Markdown content.
- Added knowledge chunking and URL parsing logic to handle webpage content extraction and formatting.
- Updated database schema to include markdown_content in knowledge_items table.
2026-04-05 20:41:42 +08:00

123 lines
2.2 KiB
Go

package app
import "strings"
func splitKnowledgeTextIntoChunks(text string, chunkSize, chunkOverlap int) []string {
text = strings.TrimSpace(text)
if text == "" {
return nil
}
if chunkSize <= 0 {
chunkSize = 900
}
if chunkOverlap < 0 {
chunkOverlap = 0
}
if chunkOverlap >= chunkSize {
chunkOverlap = chunkSize / 4
}
lines := strings.Split(text, "\n")
chunks := make([]string, 0, len(lines))
current := make([]string, 0, 16)
currentLen := 0
resetWithOverlap := func(chunk string) {
current = current[:0]
currentLen = 0
if chunkOverlap <= 0 {
return
}
overlap := takeLastKnowledgeRunes(chunk, chunkOverlap)
if overlap == "" {
return
}
current = append(current, overlap)
currentLen = len([]rune(overlap))
}
flush := func() {
if len(current) == 0 {
return
}
chunk := strings.TrimSpace(strings.Join(current, "\n"))
if chunk == "" {
current = current[:0]
currentLen = 0
return
}
chunks = append(chunks, chunk)
resetWithOverlap(chunk)
}
for _, line := range lines {
line = strings.TrimSpace(line)
if line == "" {
continue
}
lineRunes := len([]rune(line))
if lineRunes > chunkSize {
flush()
for _, segment := range splitKnowledgeLongLine(line, chunkSize) {
if strings.TrimSpace(segment) == "" {
continue
}
chunks = append(chunks, segment)
resetWithOverlap(segment)
}
continue
}
nextLen := currentLen + lineRunes
if len(current) > 0 {
nextLen++
}
if nextLen > chunkSize {
flush()
}
current = append(current, line)
currentLen += lineRunes
if len(current) > 1 {
currentLen++
}
}
if len(current) > 0 {
chunk := strings.TrimSpace(strings.Join(current, "\n"))
if chunk != "" {
chunks = append(chunks, chunk)
}
}
return chunks
}
func takeLastKnowledgeRunes(text string, size int) string {
if size <= 0 {
return ""
}
runes := []rune(strings.TrimSpace(text))
if len(runes) <= size {
return string(runes)
}
return strings.TrimSpace(string(runes[len(runes)-size:]))
}
func estimateKnowledgeTokenCount(text string) int {
text = strings.TrimSpace(text)
if text == "" {
return 0
}
runeCount := len([]rune(text))
tokenCount := runeCount / 2
if tokenCount == 0 {
return 1
}
return tokenCount
}