Spaces:
Sleeping
Sleeping
| """Chat UI components — message rendering and streaming.""" | |
| from __future__ import annotations | |
| from typing import Iterator | |
| import streamlit as st | |
| from src.serving.citation import cite, CitationResult | |
| def render_chat_history(messages: list[dict]): | |
| """Render all messages in the chat history.""" | |
| for msg in messages: | |
| with st.chat_message(msg["role"]): | |
| st.markdown(msg["content"]) | |
| def stream_response(generator: Iterator[str]) -> str: | |
| """Stream LLM output to the chat UI, return the full response text.""" | |
| with st.chat_message("assistant"): | |
| response = st.write_stream(generator) | |
| return response | |
| def render_agent_response(result) -> None: | |
| """Render agent reasoning trace + final answer in a chat bubble.""" | |
| with st.chat_message("assistant"): | |
| for i, step in enumerate(result.steps): | |
| if step.thought: | |
| st.caption("Step {} — {}".format(i + 1, step.thought)) | |
| if step.tool_call: | |
| args = ", ".join( | |
| "{}={}".format(k, v) | |
| for k, v in step.tool_call.arguments.items() | |
| ) | |
| st.info("🔧 {}({})".format(step.tool_call.tool_name, args)) | |
| if step.observation: | |
| with st.expander("Tool result (step {})".format(i + 1)): | |
| st.code(step.observation[:800], language=None) | |
| st.markdown(result.answer) | |
| def render_cited_response( | |
| answer: str, | |
| chunks: list[tuple[str, float]], | |
| threshold: float = 0.10, | |
| ) -> CitationResult: | |
| """Render an answer with citation markers and a references section. | |
| Displays the annotated answer with ``[N]`` markers inline, followed | |
| by an expandable references section showing the source chunk for | |
| each citation. | |
| Returns the CitationResult so callers can store it in session state. | |
| """ | |
| result = cite(answer, chunks, threshold=threshold) | |
| with st.chat_message("assistant"): | |
| st.markdown(result.annotated_answer) | |
| if result.citations: | |
| with st.expander( | |
| "Sources ({} citation{})".format( | |
| len(result.citations), | |
| "s" if len(result.citations) != 1 else "", | |
| ), | |
| expanded=False, | |
| ): | |
| for ref_line in result.references.split("\n"): | |
| if ref_line.strip(): | |
| st.caption(ref_line) | |
| return result | |