ForcePilot/backend/package/yuxi/channel/extensions/xmpp/streaming.py

68 lines
1.7 KiB
Python
Raw Normal View History

import asyncio
import logging
import re
logger = logging.getLogger("yuxi.channel.xmpp.streaming")
def chunk_text(
text: str,
min_chars: int = 800,
max_chars: int = 2000,
) -> list[str]:
if len(text) <= max_chars:
return [text]
paragraphs = re.split(r"\n\s*\n", text)
chunks = []
current = ""
for para in paragraphs:
candidate = f"{current}\n\n{para}".strip() if current else para
if len(candidate) > max_chars and current:
chunks.append(current)
current = para
else:
current = candidate
if current:
chunks.append(current)
merged = []
buf = ""
for chunk in chunks:
candidate = f"{buf}\n\n{chunk}".strip() if buf else chunk
if len(candidate) <= max_chars:
buf = candidate
else:
if buf:
merged.append(buf)
buf = chunk
if buf:
merged.append(buf)
return merged if merged else [text]
async def stream_xmpp_blocks(
gateway,
target_id: str,
chunks: list[str],
typing_interval_ms: int = 500,
) -> None:
from yuxi.channel.extensions.xmpp.outbound import send_xmpp_text, send_xmpp_typing
for i, chunk in enumerate(chunks):
if i == 0:
await send_xmpp_typing(gateway, target_id, composing=True)
await asyncio.sleep(typing_interval_ms / 1000.0)
await send_xmpp_text(gateway, target_id, chunk)
if i < len(chunks) - 1:
await asyncio.sleep(typing_interval_ms / 1000.0)
await send_xmpp_typing(gateway, target_id, composing=True)
await asyncio.sleep(typing_interval_ms / 1000.0)
await send_xmpp_typing(gateway, target_id, composing=False)