ForcePilot/backend/package/yuxi/channels/adapters/msteams/chunking.py

73 lines
1.9 KiB
Python
Raw Normal View History

from __future__ import annotations
def chunk_text(text: str, limit: int, mode: str = "paragraph") -> list[str]:
if len(text) <= limit:
return [text]
if mode == "length":
return _chunk_by_length(text, limit)
if mode == "newline":
return _chunk_by_newline(text, limit)
return _chunk_by_paragraph(text, limit)
def _chunk_by_paragraph(text: str, limit: int) -> list[str]:
chunks = []
paragraphs = text.split("\n\n")
for para in paragraphs:
if len(para) <= limit:
chunks.append(para)
continue
sentences = para.replace("\n", " ").split(". ")
current = ""
for sentence in sentences:
sep = ". " if current else ""
candidate = f"{current}{sep}{sentence}"
if current and len(candidate) + 1 > limit:
chunks.append(current + ".")
current = sentence
else:
current = candidate
if current:
if not current.endswith("."):
current += "."
chunks.append(current)
merged = []
for chunk in chunks:
if merged and len(merged[-1]) + len(chunk) + 2 <= limit:
merged[-1] = f"{merged[-1]}\n\n{chunk}"
else:
merged.append(chunk)
return merged
def _chunk_by_length(text: str, limit: int) -> list[str]:
chunks = []
for i in range(0, len(text), limit):
chunks.append(text[i : i + limit])
return chunks
def _chunk_by_newline(text: str, limit: int) -> list[str]:
lines = text.split("\n")
chunks = []
current = ""
for line in lines:
candidate = f"{current}\n{line}" if current else line
if len(candidate) > limit and current:
chunks.append(current)
current = line
else:
current = candidate
if current:
chunks.append(current)
return chunks