soothe-cli 0.5.4__tar.gz → 0.5.6__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/PKG-INFO +1 -1
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/cli/execution/headless.py +1 -1
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/tui/widgets/loading.py +11 -3
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/tui/widgets/messages.py +66 -9
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/.gitignore +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/README.md +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/pyproject.toml +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/__init__.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/cli/__init__.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/cli/commands/__init__.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/cli/commands/autopilot_cmd.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/cli/commands/loop_cmd.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/cli/commands/run_cmd.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/cli/execution/__init__.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/cli/execution/daemon.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/cli/execution/headless_renderer.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/cli/execution/launcher.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/cli/main.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/cli/stream/__init__.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/cli/stream/context.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/cli/stream/display_line.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/cli/stream/formatter.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/cli/stream/pipeline.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/cli/stream/task_scope.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/config/__init__.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/config/cli_config.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/plan/__init__.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/plan/rich_tree.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/shared/__init__.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/shared/commands/__init__.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/shared/commands/command_router.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/shared/commands/slash_commands.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/shared/commands/subagent_routing.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/shared/config_loader.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/shared/core/__init__.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/shared/core/event_processor.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/shared/core/presentation_engine.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/shared/core/processor_state.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/shared/core/renderer_protocol.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/shared/duration_format.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/shared/events/__init__.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/shared/events/display_policy.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/shared/events/essential_events.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/shared/events/explore_task_display.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/shared/events/stream_accumulator.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/shared/events/tui_trace_log.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/shared/rendering/__init__.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/shared/rendering/async_renderer_protocol.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/shared/rendering/renderer_base.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/shared/tools/__init__.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/shared/tools/_utils.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/shared/tools/message_processing.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/shared/tools/rendering.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/shared/tools/tool_call_resolution.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/shared/tools/tool_card_payload.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/shared/tools/tool_card_visibility.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/shared/tools/tool_formatters/__init__.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/shared/tools/tool_formatters/base.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/shared/tools/tool_formatters/execution.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/shared/tools/tool_formatters/fallback.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/shared/tools/tool_formatters/file_ops.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/shared/tools/tool_formatters/goal_formatter.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/shared/tools/tool_formatters/media.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/shared/tools/tool_formatters/structured.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/shared/tools/tool_formatters/subagent.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/shared/tools/tool_formatters/web.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/shared/tools/tool_message_format.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/shared/tools/tool_output_formatter.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/tui/__init__.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/tui/_ask_user_types.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/tui/_cli_context.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/tui/_env_vars.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/tui/_session_stats.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/tui/_version.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/tui/app/__init__.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/tui/app/_app.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/tui/app/_commands.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/tui/app/_execution.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/tui/app/_history.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/tui/app/_messages_mixin.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/tui/app/_model.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/tui/app/_module_init.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/tui/app/_startup.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/tui/app/_ui.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/tui/app/app.tcss +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/tui/command_registry.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/tui/config.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/tui/daemon_session.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/tui/file_ops.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/tui/formatting.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/tui/hooks.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/tui/input.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/tui/media_utils.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/tui/message_display_filter.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/tui/model_config.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/tui/output.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/tui/preview_limits.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/tui/project_utils.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/tui/sessions.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/tui/skills/__init__.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/tui/skills/invocation.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/tui/skills/load.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/tui/textual_adapter/__init__.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/tui/textual_adapter/_adapter.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/tui/textual_adapter/_stream_formatting.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/tui/textual_adapter/_stream_messages.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/tui/textual_adapter/_turn.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/tui/textual_adapter/_turn_helpers.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/tui/theme.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/tui/tool_display.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/tui/unicode_security.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/tui/update_check.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/tui/widgets/__init__.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/tui/widgets/_links.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/tui/widgets/approval.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/tui/widgets/ask_user.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/tui/widgets/autocomplete.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/tui/widgets/autopilot_dashboard.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/tui/widgets/autopilot_screen.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/tui/widgets/chat_input.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/tui/widgets/clipboard.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/tui/widgets/diff.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/tui/widgets/editor.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/tui/widgets/history.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/tui/widgets/loop_selector.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/tui/widgets/mcp_viewer.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/tui/widgets/message_store.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/tui/widgets/model_selector.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/tui/widgets/notification_settings.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/tui/widgets/status.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/tui/widgets/theme_selector.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/tui/widgets/tool_renderers.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/tui/widgets/tool_widgets.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/tui/widgets/tools.py +0 -0
- {soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/tui/widgets/welcome.py +0 -0
|
@@ -137,7 +137,8 @@ class LoadingWidget(Static):
|
|
|
137
137
|
now = monotonic()
|
|
138
138
|
if self._turn_start_mono is None:
|
|
139
139
|
self._turn_start_mono = now
|
|
140
|
-
|
|
140
|
+
# Reduced from 0.1s (10fps) to 0.2s (5fps) to reduce UI thread contention
|
|
141
|
+
self._animation_timer = self.set_interval(0.2, self._update_animation)
|
|
141
142
|
|
|
142
143
|
def on_unmount(self) -> None:
|
|
143
144
|
"""Stop the animation timer when the widget leaves the DOM."""
|
|
@@ -159,13 +160,20 @@ class LoadingWidget(Static):
|
|
|
159
160
|
self._animation_timer = None
|
|
160
161
|
|
|
161
162
|
def _update_animation(self) -> None:
|
|
162
|
-
"""Update spinner and elapsed time."""
|
|
163
|
+
"""Update spinner and elapsed time (optimized to reduce render overhead)."""
|
|
163
164
|
if self._paused:
|
|
164
165
|
return
|
|
165
166
|
|
|
167
|
+
# Skip update if widget is not visible on screen
|
|
168
|
+
if not self.is_on_screen:
|
|
169
|
+
return
|
|
170
|
+
|
|
166
171
|
if self._spinner_widget:
|
|
167
172
|
frame = self._spinner.next_frame()
|
|
168
|
-
|
|
173
|
+
# Use refresh with layout=False to avoid expensive layout recalculation
|
|
174
|
+
self._spinner_widget._content = frame
|
|
175
|
+
self._spinner_widget._render_cache = None
|
|
176
|
+
self._spinner_widget.refresh(repaint=True, layout=False)
|
|
169
177
|
|
|
170
178
|
if self._hint_widget and self._turn_start_mono is not None:
|
|
171
179
|
now = monotonic()
|
|
@@ -59,7 +59,7 @@ _STEP_TOOL_PREVIEW_ROWS = STEP_TASK_CARD_COLLAPSE_LINE_THRESHOLD
|
|
|
59
59
|
"""Collapsed step/task activity preview shows this many rows (IG-402)."""
|
|
60
60
|
|
|
61
61
|
_MAX_STEP_STAT_TOOL_KINDS = 4
|
|
62
|
-
"""Max distinct tool display names in the
|
|
62
|
+
"""Max distinct tool display names in the running-line stats suffix before ``+N more``."""
|
|
63
63
|
|
|
64
64
|
_RUNNING_SPINNER_INTERVAL_SECONDS = 0.2
|
|
65
65
|
"""Spinner/status animation cadence for running cards."""
|
|
@@ -711,6 +711,10 @@ class AssistantMessage(Vertical):
|
|
|
711
711
|
}
|
|
712
712
|
"""
|
|
713
713
|
|
|
714
|
+
# Performance optimization: batch streaming updates to reduce render frequency
|
|
715
|
+
_STREAM_FLUSH_INTERVAL: float = 0.05 # 50ms batching for streaming
|
|
716
|
+
_VISIBILITY_REFRESH_INTERVAL: float = 0.1 # 100ms throttle for visibility refresh
|
|
717
|
+
|
|
714
718
|
def __init__(self, content: str = "", **kwargs: Any) -> None:
|
|
715
719
|
"""Initialize an assistant message.
|
|
716
720
|
|
|
@@ -726,6 +730,11 @@ class AssistantMessage(Vertical):
|
|
|
726
730
|
self._preview_widget: Static | None = None
|
|
727
731
|
self._hint_widget: Static | None = None
|
|
728
732
|
|
|
733
|
+
# Batching buffer for streaming content
|
|
734
|
+
self._pending_buffer: str = ""
|
|
735
|
+
self._flush_timer: Timer | None = None
|
|
736
|
+
self._last_visibility_refresh: float = 0.0
|
|
737
|
+
|
|
729
738
|
def compose(self) -> ComposeResult: # noqa: PLR6301 # Textual widget method convention
|
|
730
739
|
"""Compose markdown body, plain preview, and expand hint."""
|
|
731
740
|
from textual.widgets import Markdown
|
|
@@ -851,14 +860,50 @@ class AssistantMessage(Vertical):
|
|
|
851
860
|
else:
|
|
852
861
|
_show_timestamp_toast(self)
|
|
853
862
|
|
|
863
|
+
def _should_refresh_visibility(self) -> bool:
|
|
864
|
+
"""Check if visibility refresh should run (throttled)."""
|
|
865
|
+
from time import monotonic
|
|
866
|
+
|
|
867
|
+
now = monotonic()
|
|
868
|
+
if now - self._last_visibility_refresh > self._VISIBILITY_REFRESH_INTERVAL:
|
|
869
|
+
self._last_visibility_refresh = now
|
|
870
|
+
return True
|
|
871
|
+
return False
|
|
872
|
+
|
|
873
|
+
async def _flush_pending_content(self) -> None:
|
|
874
|
+
"""Flush buffered content to stream (batched update)."""
|
|
875
|
+
self._flush_timer = None
|
|
876
|
+
if not self._pending_buffer:
|
|
877
|
+
return
|
|
878
|
+
|
|
879
|
+
text = self._pending_buffer
|
|
880
|
+
self._pending_buffer = ""
|
|
881
|
+
|
|
882
|
+
stream = self._ensure_stream()
|
|
883
|
+
await stream.write(text)
|
|
884
|
+
|
|
885
|
+
# Throttle visibility refresh
|
|
886
|
+
if self._should_refresh_visibility():
|
|
887
|
+
self._refresh_body_visibility()
|
|
888
|
+
|
|
854
889
|
async def append_content(self, text: str) -> None:
|
|
855
|
-
"""Append content to the message (for streaming).
|
|
890
|
+
"""Append content to the message (for streaming with batching).
|
|
891
|
+
|
|
892
|
+
Uses internal buffering to batch writes and reduce render frequency.
|
|
893
|
+
"""
|
|
856
894
|
if not text:
|
|
857
895
|
return
|
|
896
|
+
|
|
897
|
+
# Accumulate content
|
|
858
898
|
self._content += text
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
899
|
+
self._pending_buffer += text
|
|
900
|
+
|
|
901
|
+
# Schedule batched flush if not already scheduled
|
|
902
|
+
if self._flush_timer is None:
|
|
903
|
+
self._flush_timer = self.set_timer(
|
|
904
|
+
self._STREAM_FLUSH_INTERVAL,
|
|
905
|
+
self._flush_pending_content,
|
|
906
|
+
)
|
|
862
907
|
|
|
863
908
|
async def write_initial_content(self) -> None:
|
|
864
909
|
"""Write initial content from constructor and finalize the stream."""
|
|
@@ -869,6 +914,15 @@ class AssistantMessage(Vertical):
|
|
|
869
914
|
|
|
870
915
|
async def stop_stream(self) -> None:
|
|
871
916
|
"""Stop the streaming and apply collapsed layout when appropriate."""
|
|
917
|
+
# Cancel any pending flush timer
|
|
918
|
+
if self._flush_timer is not None:
|
|
919
|
+
self._flush_timer.stop()
|
|
920
|
+
self._flush_timer = None
|
|
921
|
+
|
|
922
|
+
# Flush any remaining buffered content
|
|
923
|
+
if self._pending_buffer:
|
|
924
|
+
await self._flush_pending_content()
|
|
925
|
+
|
|
872
926
|
if self._stream is not None:
|
|
873
927
|
await self._stream.stop()
|
|
874
928
|
self._stream = None
|
|
@@ -878,6 +932,7 @@ class AssistantMessage(Vertical):
|
|
|
878
932
|
"""Set the full message content (stops any active stream)."""
|
|
879
933
|
await self.stop_stream()
|
|
880
934
|
self._content = content
|
|
935
|
+
self._pending_buffer = "" # Clear any pending buffer
|
|
881
936
|
if self._markdown:
|
|
882
937
|
await self._markdown.update(content)
|
|
883
938
|
self._refresh_body_visibility()
|
|
@@ -2461,8 +2516,9 @@ class _StepToolRow:
|
|
|
2461
2516
|
class CognitionStepMessage(Vertical):
|
|
2462
2517
|
"""Agent-loop act step card: aggregates main-agent tool calls (IG-402).
|
|
2463
2518
|
|
|
2464
|
-
Header
|
|
2465
|
-
|
|
2519
|
+
Header is the step description only; per-tool counts appear on the running
|
|
2520
|
+
status line (and match the prior header format). Body lists one CLI-style row
|
|
2521
|
+
per call. When there are more than ``_STEP_TOOL_PREVIEW_ROWS`` rows, click first folds or
|
|
2466
2522
|
unfolds the tool list; otherwise click toggles whole-card collapse. When tool
|
|
2467
2523
|
rows, subagent notes, and execute prose together exceed that same threshold,
|
|
2468
2524
|
the card body auto-collapses until the user expands it (a new ``set_running``
|
|
@@ -2630,7 +2686,7 @@ class CognitionStepMessage(Vertical):
|
|
|
2630
2686
|
return _assemble_card_header(
|
|
2631
2687
|
self,
|
|
2632
2688
|
"🚀 ",
|
|
2633
|
-
|
|
2689
|
+
self._description,
|
|
2634
2690
|
)
|
|
2635
2691
|
|
|
2636
2692
|
def compose(self) -> ComposeResult:
|
|
@@ -3169,7 +3225,8 @@ class CognitionStepMessage(Vertical):
|
|
|
3169
3225
|
toggle_icon = ""
|
|
3170
3226
|
if has_collapsible:
|
|
3171
3227
|
toggle_icon = f" {g.expand if self._card_collapsed else g.collapse}"
|
|
3172
|
-
|
|
3228
|
+
stats_suffix = self._stats_title_suffix()
|
|
3229
|
+
line = f"{gutter}{frame} Running...{elapsed}{stats_suffix}{toggle_icon}"
|
|
3173
3230
|
self._status_widget.update(Content.styled(line, colors.cognition))
|
|
3174
3231
|
now = monotonic()
|
|
3175
3232
|
if any(r.phase == "running" for r in self._rows) and (
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/shared/rendering/async_renderer_protocol.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/shared/tools/tool_formatters/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/shared/tools/tool_formatters/execution.py
RENAMED
|
File without changes
|
{soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/shared/tools/tool_formatters/fallback.py
RENAMED
|
File without changes
|
{soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/shared/tools/tool_formatters/file_ops.py
RENAMED
|
File without changes
|
{soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/shared/tools/tool_formatters/goal_formatter.py
RENAMED
|
File without changes
|
|
File without changes
|
{soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/shared/tools/tool_formatters/structured.py
RENAMED
|
File without changes
|
{soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/shared/tools/tool_formatters/subagent.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/tui/textual_adapter/_stream_formatting.py
RENAMED
|
File without changes
|
{soothe_cli-0.5.4 → soothe_cli-0.5.6}/src/soothe_cli/tui/textual_adapter/_stream_messages.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|