{#- chirp-ui: Streaming and AI components For LLM Playground, RAG demo, and SSE-driven UIs. Works with htmx SSE and event delegation for copy buttons. Usage: {% from "chirpui/streaming.html" import streaming_block, copy_btn, prose %} {% call streaming_block(streaming=true) %} Content or thinking... {% end %} {% call copy_btn(text="Copy", copy_text=answer_text) %}
{{ content | markdown | safe(reason="markdown output") }}
-#} {% def streaming_bubble(role="assistant", state="", streaming=true, sse_swap_target=false, sse_connect=none, sse_close="done", cls="") %} {% set role_valid = role | validate_variant_block("message_bubble", default="assistant") %} {% set _state = state | validate_variant(("", "content", "thinking", "error"), "") %} {% set role_class = " chirpui-message-bubble--" ~ role_valid if role_valid != "default" else "" %} {% set state_class = " chirpui-streaming-bubble--" ~ _state if _state and _state != "content" else "" %} {% set _aria_labels = {"assistant": "assistant response", "user": "user message", "system": "system message", "default": "message"} %} {# @provides _streaming_role — consumed by: copy_button #} {% provide _streaming_role = role_valid %} {% end %} {% end %} {% def streaming_block(streaming=false, sse_swap_target=false, cls="") %}
{% try %} {% slot %} {% if streaming %} {% end %} {% fallback %} {% end %}
{% end %} {% def copy_btn(label="Copy", copy_text="", cls="") %} {% end %} {% def model_card(title, badge=none, footer=none, cls="", sse_connect=none, sse_close="done", sse_streaming=false) %}
{{ title }} {% if badge %} {{ badge }} {% end %}
{% if sse_streaming %}
{% slot %}
{% else %} {% slot %} {% end %}
{% if footer %} {% end %}
{% end %}