import streamlit as st class OutputDisplay: """ Renders structured execution results and debug logs. """ # ---------------- MAIN RENDERER ---------------- def render_output(self, result: dict): success = result["returncode"] == 0 status_icon = "✅" if success else "❌" st.markdown(f"**{status_icon} Exited {result['returncode']}**") if result["stdout"].strip(): st.caption("stdout") st.code(result["stdout"].rstrip(), language="text") if result["stderr"].strip(): st.caption("stderr") st.code(result["stderr"].rstrip(), language="text") if result.get("logs"): with st.expander("🪲 Debug log", expanded=False): level_colors = { "INFO": "#6c7086", "OUTPUT": "#a6e3a1", "ERROR": "#f38ba8", "SYNTAX": "#fab387", "EXCEPTION": "#f38ba8", "SUCCESS": "#a6e3a1", "FAIL": "#f38ba8", } icons = { "INFO": "ℹ", "OUTPUT": "▶", "ERROR": "✖", "SYNTAX": "⚠", "EXCEPTION": "💥", "SUCCESS": "✔", "FAIL": "✖", } lines = [] for e in result["logs"]: color = level_colors.get(e["level"], "#cdd6f4") icon = icons.get(e["level"], "•") lines.append( f'[{e["time"]}] ' f'{icon} {e["level"]} : ' f'{e["message"]}' ) st.markdown("
".join(lines), unsafe_allow_html=True) if not result["stdout"].strip() and not result["stderr"].strip(): st.caption("No output.") # ---------------- HELPERS ---------------- def display_error(self, error_message: str): st.error(f"❌ {error_message}") def display_warning(self, warning_message: str): st.warning(f"⚠️ {warning_message}")