Yash030/claude-code-proxy
2
1"""Throttled platform UI updates driven by transcript rendering."""2 3from __future__ import annotations4 5import time6from collections.abc import Callable7 8from loguru import logger9 10from .platforms.base import MessagingPlatform11from .safe_diagnostics import format_exception_for_log12from .transcript import RenderCtx, TranscriptBuffer13 14 15class ThrottledTranscriptEditor:16 """Rate-limited status message edits from a growing transcript."""17 18 def __init__(19 self,20 *,21 platform: MessagingPlatform,22 parse_mode: str | None,23 get_limit_chars: Callable[[], int],24 transcript: TranscriptBuffer,25 render_ctx: RenderCtx,26 node_id: str,27 chat_id: str,28 status_msg_id: str,29 debug_platform_edits: bool,30 log_messaging_error_details: bool = False,31 ) -> None:32 self._platform = platform33 self._parse_mode = parse_mode34 self._get_limit_chars = get_limit_chars35 self._transcript = transcript36 self._render_ctx = render_ctx37 self._node_id = node_id38 self._chat_id = chat_id39 self._status_msg_id = status_msg_id40 self._debug_platform_edits = debug_platform_edits41 self._log_messaging_error_details = log_messaging_error_details42 self._last_ui_update = 0.043 self._last_displayed_text: str | None = None44 self._last_status: str | None = None45 46 @property47 def last_status(self) -> str | None:48 return self._last_status49 50 async def update(self, status: str | None = None, *, force: bool = False) -> None:51 """Render transcript + optional status line and edit the platform message."""52 now = time.time()53 if not force and now - self._last_ui_update < 1.0:54 return55 56 self._last_ui_update = now57 if status is not None:58 self._last_status = status59 try:60 display = self._transcript.render(61 self._render_ctx,62 limit_chars=self._get_limit_chars(),63 status=status,64 )65 except Exception as e:66 logger.warning(67 "Transcript render failed for node {}: {}",68 self._node_id,69 format_exception_for_log(70 e, log_full_message=self._log_messaging_error_details71 ),72 )73 return74 if display and display != self._last_displayed_text:75 logger.debug(76 "PLATFORM_EDIT: node_id={} chat_id={} msg_id={} force={} status={!r} chars={}",77 self._node_id,78 self._chat_id,79 self._status_msg_id,80 bool(force),81 status,82 len(display),83 )84 if self._debug_platform_edits:85 logger.debug("PLATFORM_EDIT_TEXT:\n{}", display)86 self._last_displayed_text = display87 try:88 await self._platform.queue_edit_message(89 self._chat_id,90 self._status_msg_id,91 display,92 parse_mode=self._parse_mode,93 )94 except Exception as e:95 logger.warning(96 "Failed to update platform for node {}: {}",97 self._node_id,98 format_exception_for_log(99 e, log_full_message=self._log_messaging_error_details100 ),101 )102 