from anthropic.types import Message, TextBlock, ThinkingBlock, ToolUseBlock, Usage from beaver_gateway.frontends.markdown import renderer def _message(*blocks: object) -> Message: return Message( id="m", type="message", role="assistant", model="x", content=list(blocks), # type: ignore[arg-type] stop_reason="end_turn", stop_sequence=None, usage=Usage(input_tokens=1, output_tokens=1), ) def test_tool_calls_leave_no_blank_lines() -> None: message = _message( TextBlock(type="text", text="first"), ToolUseBlock(type="tool_use", id="t1", name="Bash", input={"command": "ls"}), ToolUseBlock(type="tool_use", id="t2", name="Read", input={"file_path": "x"}), ToolUseBlock(type="tool_use", id="t3", name="Grep", input={"pattern": "y"}), TextBlock(type="text", text="second"), ) assert renderer.render_assistant_message(message) == ( "### Assistant:\n\nfirst\n\nsecond\n" ) def test_thinking_renders_as_collapsed_callout() -> None: message = _message( ThinkingBlock(type="thinking", thinking="a\nb", signature="s"), TextBlock(type="text", text="answer"), ) assert renderer.render_assistant_message(message) == ( "### Assistant:\n\n> [!thinking]-\n> a\n> b\n\nanswer\n" ) def test_thinking_between_hidden_tool_calls_collapses_to_the_first() -> None: message = _message( ThinkingBlock(type="thinking", thinking="one", signature="s"), ToolUseBlock(type="tool_use", id="t1", name="Read", input={}), ThinkingBlock(type="thinking", thinking="two", signature="s"), ToolUseBlock(type="tool_use", id="t2", name="Read", input={}), ThinkingBlock(type="thinking", thinking="three", signature="s"), TextBlock(type="text", text="answer"), ThinkingBlock(type="thinking", thinking="four", signature="s"), TextBlock(type="text", text="more"), ) assert renderer.render_assistant_message(message) == ( "### Assistant:\n\n> [!thinking]-\n> one\n\nanswer\n\n" "> [!thinking]-\n> four\n\nmore\n" ) def test_user_scaffold_matches_rendered_user_turn_shape() -> None: body = renderer.append_to_body("### Assistant:\n\nhi\n", renderer.USER_SCAFFOLD) assert body.endswith("\n\n---\n\n### User:\n\n") assert renderer.render_user_text("q").startswith("### User:\n\n")