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