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

68 lines
2.1 KiB
Python
Raw Normal View History

import logging
import time
from yuxi.channel.extensions.intercom.constants import (
INTERCOM_BLOCK_STREAMING_CHUNK_MIN_CHARS,
INTERCOM_BLOCK_STREAMING_CHUNK_MAX_CHARS,
)
logger = logging.getLogger(__name__)
class IntercomStreaming:
streaming_mode = "block"
preview_stream_throttle_ms = 2000
preview_min_initial_chars = 100
block_streaming_enabled = True
block_streaming_break = "\n"
block_streaming_chunk_min_chars = INTERCOM_BLOCK_STREAMING_CHUNK_MIN_CHARS
block_streaming_chunk_max_chars = INTERCOM_BLOCK_STREAMING_CHUNK_MAX_CHARS
block_streaming_chunk_break_preference = "paragraph"
block_streaming_coalesce_defaults = None
def create_draft_stream_session(self, target_id: str) -> object:
return {"target_id": target_id, "content": ""}
def create_block_chunker(self) -> object:
return {"mode": "length"}
async def stream_reply(
self,
client,
conversation_id: str,
full_text_generator,
bot_admin_id: str,
) -> str:
accumulated = ""
note_id = None
last_note_update = 0.0
NOTE_THROTTLE = 2.0
async for chunk in full_text_generator:
accumulated += chunk
now = time.monotonic()
if note_id is None:
try:
resp = await client.reply_conversation(
conversation_id,
"正在生成回复...",
message_type="note",
reply_type="admin",
admin_id=bot_admin_id,
)
note_id = resp.get("id", "")
except Exception:
logger.warning("Failed to create draft note for streaming")
if now - last_note_update >= NOTE_THROTTLE and len(accumulated) > 100:
last_note_update = now
if note_id:
try:
await client.delete_conversation_part(conversation_id, str(note_id))
except Exception:
logger.warning("Failed to delete draft note %s", note_id)
return accumulated