diff --git a/src/storied/cli.py b/src/storied/cli.py --- a/src/storied/cli.py +++ b/src/storied/cli.py @@ -488,21 +488,26 @@ action = f"[System: The player wants to add a note to their character sheet. Use update_character with section.Notes to append this note, preserving any existing notes. Note to add: {note_msg}]" try: console.print(Rule(style="dim blue")) - console.print() # Blank line before DM response renderer = StreamRenderer(console) prev_type: str | None = None + got_text = False for chunk in engine.stream_action(action): - if chunk.startswith("\n[") or chunk.startswith("Rolled "): - if prev_type != "tool": + if chunk.startswith("[") and chunk.endswith("]") and "..." in chunk: + if prev_type == "text": renderer.flush() - console.file.write("\n") - console.print() - console.print(f"[dim]{chunk.strip()}[/dim]") + console.file.write("\n\n") + console.print(f"[dim]{chunk}[/dim]") prev_type = "tool" else: if prev_type == "tool": console.print() + if not got_text: + chunk = chunk.lstrip("\n") + if not chunk: + continue + chunk = "\n" + chunk + got_text = True renderer.feed(chunk) prev_type = "text" diff --git a/src/storied/engine.py b/src/storied/engine.py --- a/src/storied/engine.py +++ b/src/storied/engine.py @@ -73,7 +73,7 @@ "condition": "Updating condition", "end_initiative": "Ending initiative", } label = labels.get(short, short) - return f"\n[{label}...]\n" + return f"[{label}...]" class DMEngine: @@ -435,7 +435,7 @@ if short == "roll" and not self.debug: deferred_notification = True elif self.debug: - yield f"\n[→ {short}(...)]\n" + yield f"[→ {short}(...)]" deferred_notification = False else: yield _tool_notification(name) @@ -448,7 +448,7 @@ case ToolStop(): if deferred_notification and current_tool_name == "roll": reason = _extract_roll_reason(current_tool_json) label = f"Rolling {reason}" if reason else "Rolling" - yield f"\n[{label}...]\n" + yield f"[{label}...]" if self.debug and current_tool_json: truncated = current_tool_json[:200]