feat(agents,backends,conversations,frontends,ui): progress thinking is told apart by its agent, raycast reasoning stays collapsed, read_conversation keeps progress
This commit is contained in:
1 parent
13873f857b
commit
120985deab
18 files changed
+374
-110
No files matched your search
@@ -1,7 +1,7 @@
|
||||
"""Render Anthropic ``Message`` (and user turns) into markdown.
|
||||
|
||||
One-way: produces the human-facing artifact only. The parser strips
|
||||
the tool/thinking callouts of older files when reshaping history for replay.
|
||||
tool/thinking callouts separately when reshaping history for backend replay.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
@@ -43,17 +43,25 @@ def render_assistant_text(text: str) -> str:
|
||||
return f"### Assistant:\n\n{text.strip()}\n"
|
||||
|
||||
|
||||
def render_assistant_message(message: Message) -> str:
|
||||
def render_assistant_message(message: Message, *, thinking_is_progress: bool) -> str:
|
||||
"""Render an assistant ``Message`` into a turn block.
|
||||
|
||||
Tool-use blocks and empty thinking render to nothing; a non-empty thinking
|
||||
block is what the model wrote between tool calls and renders as text.
|
||||
Tool-use blocks render to nothing. Progress thinking renders as text in
|
||||
place and vanishes when empty; reasoning renders as a collapsed callout,
|
||||
of which only the first between two texts reaches the file.
|
||||
"""
|
||||
parts: list[str] = ["### Assistant:", ""]
|
||||
after_reasoning = False
|
||||
for block in message.content:
|
||||
if isinstance(block, ThinkingBlock) and not thinking_is_progress:
|
||||
if not after_reasoning:
|
||||
parts.extend((*_render_reasoning(block.thinking or ""), ""))
|
||||
after_reasoning = True
|
||||
continue
|
||||
text = _spoken(block)
|
||||
if text:
|
||||
parts.extend((text, ""))
|
||||
after_reasoning = False
|
||||
return "\n".join(parts).rstrip() + "\n"
|
||||
|
||||
|
||||
@@ -99,6 +107,11 @@ def summarize_tool_input(name: str, tool_input: object) -> str:
|
||||
return name
|
||||
|
||||
|
||||
def _render_reasoning(text: str) -> tuple[str, ...]:
|
||||
lines = text.strip().splitlines() or [""]
|
||||
return ("> [!thinking]-", *(f"> {line}" if line else ">" for line in lines))
|
||||
|
||||
|
||||
def _spoken(block: object) -> str:
|
||||
if isinstance(block, TextBlock):
|
||||
return (block.text or "").strip()
|
||||
|
||||
Reference in new issue
Block a user