67 lines
2.2 KiB
Python
67 lines
2.2 KiB
Python
from __future__ import annotations
|
|
|
|
|
|
from .outbound import EmailSmtpOutboundAdapter
|
|
|
|
|
|
class EmailSmtpStreamingAdapter:
|
|
streaming_mode = "block"
|
|
preview_stream_throttle_ms = 160
|
|
preview_min_initial_chars = 18
|
|
block_streaming_enabled = True
|
|
block_streaming_break = "text_end"
|
|
block_streaming_chunk_min_chars = 800
|
|
block_streaming_chunk_max_chars = 1200
|
|
block_streaming_chunk_break_preference = "paragraph"
|
|
block_streaming_coalesce_defaults = None
|
|
|
|
def __init__(self, outbound: EmailSmtpOutboundAdapter | None = None):
|
|
self._outbound = outbound or EmailSmtpOutboundAdapter()
|
|
self._idle_ms = 800
|
|
|
|
def create_block_chunker(self) -> BlockChunker:
|
|
return BlockChunker(
|
|
min_chars=self.block_streaming_chunk_min_chars,
|
|
max_chars=self.block_streaming_chunk_max_chars,
|
|
break_preference=self.block_streaming_chunk_break_preference,
|
|
)
|
|
|
|
def create_draft_stream_session(self, target_id: str) -> dict:
|
|
return {
|
|
"target_id": target_id,
|
|
"accumulated": "",
|
|
"chunks_sent": 0,
|
|
}
|
|
|
|
|
|
class BlockChunker:
|
|
def __init__(self, min_chars: int = 800, max_chars: int = 1200, break_preference: str = "paragraph"):
|
|
self._min_chars = min_chars
|
|
self._max_chars = max_chars
|
|
self._break_preference = break_preference
|
|
|
|
def chunk(self, text: str) -> list[str]:
|
|
if len(text) <= self._max_chars:
|
|
return [text] if text else []
|
|
|
|
chunks = []
|
|
remaining = text
|
|
while len(remaining) > self._max_chars:
|
|
split_at = self._max_chars
|
|
if self._break_preference == "paragraph":
|
|
para_break = remaining.rfind("\n\n", 0, self._max_chars)
|
|
if para_break > self._min_chars:
|
|
split_at = para_break + 2
|
|
else:
|
|
line_break = remaining.rfind("\n", 0, self._max_chars)
|
|
if line_break > self._min_chars:
|
|
split_at = line_break + 1
|
|
|
|
chunks.append(remaining[:split_at].strip())
|
|
remaining = remaining[split_at:].strip()
|
|
|
|
if remaining:
|
|
chunks.append(remaining)
|
|
|
|
return chunks
|