soothe-cli 0.5.8__tar.gz → 0.5.9__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.
Files changed (138) hide show
  1. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/PKG-INFO +1 -1
  2. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/cli/execution/daemon.py +8 -0
  3. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/shared/core/event_processor.py +14 -7
  4. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/tui/app/_history.py +1 -3
  5. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/tui/daemon_session.py +1 -0
  6. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/tui/textual_adapter/_turn_helpers.py +2 -3
  7. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/tui/widgets/messages.py +10 -8
  8. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/.gitignore +0 -0
  9. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/README.md +0 -0
  10. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/pyproject.toml +0 -0
  11. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/__init__.py +0 -0
  12. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/cli/__init__.py +0 -0
  13. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/cli/commands/__init__.py +0 -0
  14. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/cli/commands/autopilot_cmd.py +0 -0
  15. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/cli/commands/loop_cmd.py +0 -0
  16. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/cli/commands/run_cmd.py +0 -0
  17. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/cli/execution/__init__.py +0 -0
  18. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/cli/execution/headless.py +0 -0
  19. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/cli/execution/headless_renderer.py +0 -0
  20. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/cli/execution/launcher.py +0 -0
  21. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/cli/main.py +0 -0
  22. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/cli/stream/__init__.py +0 -0
  23. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/cli/stream/context.py +0 -0
  24. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/cli/stream/display_line.py +0 -0
  25. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/cli/stream/formatter.py +0 -0
  26. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/cli/stream/pipeline.py +0 -0
  27. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/cli/stream/task_scope.py +0 -0
  28. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/config/__init__.py +0 -0
  29. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/config/cli_config.py +0 -0
  30. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/plan/__init__.py +0 -0
  31. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/plan/rich_tree.py +0 -0
  32. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/shared/__init__.py +0 -0
  33. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/shared/commands/__init__.py +0 -0
  34. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/shared/commands/command_router.py +0 -0
  35. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/shared/commands/slash_commands.py +0 -0
  36. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/shared/commands/subagent_routing.py +0 -0
  37. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/shared/config_loader.py +0 -0
  38. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/shared/core/__init__.py +0 -0
  39. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/shared/core/presentation_engine.py +0 -0
  40. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/shared/core/processor_state.py +0 -0
  41. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/shared/core/renderer_protocol.py +0 -0
  42. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/shared/daemon_errors.py +0 -0
  43. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/shared/duration_format.py +0 -0
  44. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/shared/events/__init__.py +0 -0
  45. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/shared/events/display_policy.py +0 -0
  46. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/shared/events/essential_events.py +0 -0
  47. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/shared/events/explore_task_display.py +0 -0
  48. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/shared/events/stream_accumulator.py +0 -0
  49. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/shared/events/tui_trace_log.py +0 -0
  50. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/shared/rendering/__init__.py +0 -0
  51. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/shared/rendering/async_renderer_protocol.py +0 -0
  52. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/shared/rendering/renderer_base.py +0 -0
  53. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/shared/tools/__init__.py +0 -0
  54. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/shared/tools/_utils.py +0 -0
  55. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/shared/tools/message_processing.py +0 -0
  56. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/shared/tools/rendering.py +0 -0
  57. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/shared/tools/tool_call_resolution.py +0 -0
  58. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/shared/tools/tool_card_payload.py +0 -0
  59. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/shared/tools/tool_card_visibility.py +0 -0
  60. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/shared/tools/tool_formatters/__init__.py +0 -0
  61. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/shared/tools/tool_formatters/base.py +0 -0
  62. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/shared/tools/tool_formatters/execution.py +0 -0
  63. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/shared/tools/tool_formatters/fallback.py +0 -0
  64. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/shared/tools/tool_formatters/file_ops.py +0 -0
  65. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/shared/tools/tool_formatters/goal_formatter.py +0 -0
  66. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/shared/tools/tool_formatters/media.py +0 -0
  67. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/shared/tools/tool_formatters/structured.py +0 -0
  68. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/shared/tools/tool_formatters/subagent.py +0 -0
  69. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/shared/tools/tool_formatters/web.py +0 -0
  70. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/shared/tools/tool_message_format.py +0 -0
  71. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/shared/tools/tool_output_formatter.py +0 -0
  72. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/tui/__init__.py +0 -0
  73. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/tui/_ask_user_types.py +0 -0
  74. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/tui/_cli_context.py +0 -0
  75. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/tui/_env_vars.py +0 -0
  76. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/tui/_session_stats.py +0 -0
  77. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/tui/_version.py +0 -0
  78. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/tui/app/__init__.py +0 -0
  79. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/tui/app/_app.py +0 -0
  80. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/tui/app/_commands.py +0 -0
  81. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/tui/app/_execution.py +0 -0
  82. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/tui/app/_messages_mixin.py +0 -0
  83. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/tui/app/_model.py +0 -0
  84. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/tui/app/_module_init.py +0 -0
  85. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/tui/app/_startup.py +0 -0
  86. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/tui/app/_ui.py +0 -0
  87. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/tui/app/app.tcss +0 -0
  88. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/tui/command_registry.py +0 -0
  89. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/tui/config.py +0 -0
  90. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/tui/file_ops.py +0 -0
  91. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/tui/formatting.py +0 -0
  92. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/tui/hooks.py +0 -0
  93. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/tui/input.py +0 -0
  94. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/tui/media_utils.py +0 -0
  95. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/tui/message_display_filter.py +0 -0
  96. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/tui/model_config.py +0 -0
  97. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/tui/output.py +0 -0
  98. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/tui/preview_limits.py +0 -0
  99. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/tui/project_utils.py +0 -0
  100. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/tui/sessions.py +0 -0
  101. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/tui/skills/__init__.py +0 -0
  102. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/tui/skills/invocation.py +0 -0
  103. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/tui/skills/load.py +0 -0
  104. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/tui/step_task_routing.py +0 -0
  105. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/tui/textual_adapter/__init__.py +0 -0
  106. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/tui/textual_adapter/_adapter.py +0 -0
  107. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/tui/textual_adapter/_stream_formatting.py +0 -0
  108. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/tui/textual_adapter/_stream_messages.py +0 -0
  109. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/tui/textual_adapter/_stream_tool_wire.py +0 -0
  110. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/tui/textual_adapter/_turn.py +0 -0
  111. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/tui/theme.py +0 -0
  112. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/tui/tool_display.py +0 -0
  113. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/tui/unicode_security.py +0 -0
  114. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/tui/update_check.py +0 -0
  115. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/tui/widgets/__init__.py +0 -0
  116. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/tui/widgets/_links.py +0 -0
  117. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/tui/widgets/approval.py +0 -0
  118. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/tui/widgets/ask_user.py +0 -0
  119. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/tui/widgets/autocomplete.py +0 -0
  120. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/tui/widgets/autopilot_dashboard.py +0 -0
  121. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/tui/widgets/autopilot_screen.py +0 -0
  122. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/tui/widgets/chat_input.py +0 -0
  123. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/tui/widgets/clipboard.py +0 -0
  124. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/tui/widgets/diff.py +0 -0
  125. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/tui/widgets/editor.py +0 -0
  126. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/tui/widgets/history.py +0 -0
  127. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/tui/widgets/loading.py +0 -0
  128. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/tui/widgets/loop_selector.py +0 -0
  129. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/tui/widgets/mcp_viewer.py +0 -0
  130. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/tui/widgets/message_store.py +0 -0
  131. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/tui/widgets/model_selector.py +0 -0
  132. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/tui/widgets/notification_settings.py +0 -0
  133. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/tui/widgets/status.py +0 -0
  134. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/tui/widgets/theme_selector.py +0 -0
  135. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/tui/widgets/tool_renderers.py +0 -0
  136. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/tui/widgets/tool_widgets.py +0 -0
  137. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/tui/widgets/tools.py +0 -0
  138. {soothe_cli-0.5.8 → soothe_cli-0.5.9}/src/soothe_cli/tui/widgets/welcome.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: soothe-cli
3
- Version: 0.5.8
3
+ Version: 0.5.9
4
4
  Summary: Soothe CLI client - communicates with daemon via WebSocket
5
5
  Project-URL: Homepage, https://github.com/OpenSoothe/soothe
6
6
  Project-URL: Documentation, https://soothe.readthedocs.io
@@ -65,10 +65,17 @@ async def _run_headless_session_once(
65
65
  try:
66
66
  await connect_websocket_with_retries(client)
67
67
  cli_ws = os.environ.get("SOOTHE_CLI_WORKSPACE", "").strip() or os.getcwd()
68
+ stream_delivery = "batch"
69
+ if getattr(cfg, "output_streaming_mode", None) == "streaming":
70
+ stream_delivery = "full"
71
+ elif getattr(cfg, "output_streaming_mode", None) == "merged":
72
+ stream_delivery = "merged"
73
+
68
74
  status_event = await bootstrap_loop_session(
69
75
  client,
70
76
  resume_loop_id=resume_loop_id,
71
77
  verbosity="normal",
78
+ stream_delivery=stream_delivery,
72
79
  workspace=cli_ws,
73
80
  subscribe_timeout_s=_SESSION_BOOTSTRAP_TIMEOUT_S,
74
81
  )
@@ -102,6 +109,7 @@ async def _run_headless_session_once(
102
109
  renderer,
103
110
  presentation_engine=presentation,
104
111
  headless_output=True,
112
+ streaming_mode="batch" if stream_delivery == "batch" else "streaming",
105
113
  )
106
114
 
107
115
  query_started = False
@@ -85,6 +85,7 @@ class EventProcessor:
85
85
  presentation_engine: PresentationEngine | None = None,
86
86
  tui_debug: bool = False,
87
87
  headless_output: bool = False,
88
+ streaming_mode: str | None = "batch",
88
89
  ) -> None:
89
90
  """Initialize processor with renderer.
90
91
 
@@ -94,10 +95,12 @@ class EventProcessor:
94
95
  ``presentation_engine`` when present, else a new instance.
95
96
  tui_debug: When True, emit INFO logs on logger ``soothe.ux.tui.trace`` (IG-129).
96
97
  headless_output: Headless CLI: loop-tagged main answers only, no tool/progress UI.
98
+ streaming_mode: Client display mode — ``batch`` (default), ``merged``, or ``streaming``.
97
99
  """
98
100
  self._renderer = renderer
99
101
  self._headless_output = headless_output
100
102
  self._tui_debug = tui_debug
103
+ self._streaming_mode_override = streaming_mode
101
104
 
102
105
  rebind = getattr(renderer, "_rebind_presentation", None)
103
106
  shared_from_renderer = getattr(renderer, "presentation_engine", None)
@@ -1104,12 +1107,16 @@ class EventProcessor:
1104
1107
  Returns:
1105
1108
  Dict with enabled, mode, and synthesis_streaming fields.
1106
1109
  """
1107
- # Use defaults - streaming is enabled by default per RFC-614
1108
- # Always use streaming mode
1109
- config = {
1110
+ override = getattr(self, "_streaming_mode_override", None) or "batch"
1111
+ if override in ("streaming", "full"):
1112
+ mode = "streaming"
1113
+ elif override in ("batch", "merged"):
1114
+ mode = override
1115
+ else:
1116
+ mode = "batch"
1117
+
1118
+ return {
1110
1119
  "enabled": True,
1111
- "mode": "streaming",
1112
- "synthesis_streaming": True,
1120
+ "mode": mode,
1121
+ "synthesis_streaming": mode in ("streaming", "merged"),
1113
1122
  }
1114
-
1115
- return config
@@ -278,11 +278,9 @@ class _HistoryMixin:
278
278
  return None
279
279
 
280
280
  try:
281
- from langchain_core.messages.base import messages_to_dict
282
-
283
281
  await self._daemon_session.aupdate_loop_state(
284
282
  loop_id,
285
- {"messages": messages_to_dict(recovered_messages)},
283
+ {"messages": [m.model_dump() for m in recovered_messages]},
286
284
  timeout=10.0,
287
285
  )
288
286
  logger.info(
@@ -57,6 +57,7 @@ class TuiDaemonSession:
57
57
  self._client,
58
58
  resume_loop_id=resume_loop_id,
59
59
  verbosity="normal",
60
+ stream_delivery="merged",
60
61
  workspace=self._workspace,
61
62
  )
62
63
  if status_event.get("type") == "error":
@@ -206,7 +206,6 @@ async def _handle_interrupt_cleanup(
206
206
  import time
207
207
 
208
208
  from langchain_core.messages import HumanMessage
209
- from langchain_core.messages.base import messages_to_dict
210
209
 
211
210
  # Clear active message immediately so it won't block pruning.
212
211
  # If we don't do this, the store still thinks it's active and protects
@@ -235,12 +234,12 @@ async def _handle_interrupt_cleanup(
235
234
  if interrupted_msg:
236
235
  await daemon_session.aupdate_loop_state(
237
236
  loop_id,
238
- {"messages": messages_to_dict([interrupted_msg])},
237
+ {"messages": [interrupted_msg.model_dump()]},
239
238
  timeout=2.0,
240
239
  )
241
240
  await daemon_session.aupdate_loop_state(
242
241
  loop_id,
243
- {"messages": messages_to_dict([cancellation_msg])},
242
+ {"messages": [cancellation_msg.model_dump()]},
244
243
  timeout=2.0,
245
244
  )
246
245
  except Exception:
@@ -1422,14 +1422,15 @@ class ToolCallMessage(Vertical):
1422
1422
 
1423
1423
  def _refresh_activity_display(self) -> None:
1424
1424
  """Update the unified activity widget with interleaved text lines and tool rows."""
1425
- # IG-420: Throttle refreshes to prevent UI lag during streaming
1426
- if not _should_refresh_now(self._last_activity_refresh):
1427
- return
1428
- self._last_activity_refresh = monotonic()
1425
+ # IG-420: When widget not mounted, always run auto-collapse checks (no throttling)
1429
1426
  if self._activity_widget is None:
1430
1427
  self._maybe_auto_fold_task_activity_list()
1431
1428
  self._maybe_auto_collapse_task_card()
1432
1429
  return
1430
+ # IG-420: Throttle refreshes to prevent UI lag during streaming (only when mounted)
1431
+ if not _should_refresh_now(self._last_activity_refresh):
1432
+ return
1433
+ self._last_activity_refresh = monotonic()
1433
1434
  if not self._activity:
1434
1435
  self._activity_widget.display = False
1435
1436
  self._maybe_auto_collapse_task_card()
@@ -3100,14 +3101,15 @@ class CognitionStepMessage(Vertical):
3100
3101
  return result
3101
3102
 
3102
3103
  def _refresh_tools_display(self) -> None:
3103
- # IG-420: Throttle refreshes to prevent UI lag during streaming
3104
- if not _should_refresh_now(self._last_tools_refresh):
3105
- return
3106
- self._last_tools_refresh = monotonic()
3104
+ # IG-420: When widget not mounted, always run auto-collapse checks (no throttling)
3107
3105
  if self._tools_widget is None:
3108
3106
  self._maybe_auto_fold_step_tool_list()
3109
3107
  self._maybe_auto_collapse_step_card()
3110
3108
  return
3109
+ # IG-420: Throttle refreshes to prevent UI lag during streaming (only when mounted)
3110
+ if not _should_refresh_now(self._last_tools_refresh):
3111
+ return
3112
+ self._last_tools_refresh = monotonic()
3111
3113
  if not self._rows:
3112
3114
  self._tools_widget.display = False
3113
3115
  self._maybe_auto_collapse_step_card()
File without changes
File without changes
File without changes