From 7a9ccc40faf1c79b328983a6579c1a56571952ef Mon Sep 17 00:00:00 2001 From: Amit Kumar Date: Sat, 16 May 2026 09:27:34 +0000 Subject: [PATCH 1/2] feat(ui): Task 70 Streamlit deprecation banner - src/runtime/ui.py: top-of-page st.warning() banner explaining the React UI is the supported path in v2.0.0-rc1 and Streamlit will be removed in v2.1. Suppressible via ASR_HIDE_STREAMLIT_DEPRECATION=1. Link target configurable via ASR_REACT_URL (default http://localhost:8000/). - dist/ui.py regenerated (HARD-08). --- dist/ui.py | 22 ++++++++++++++++++++++ src/runtime/ui.py | 22 ++++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/dist/ui.py b/dist/ui.py index 24f5876..1c17f21 100644 --- a/dist/ui.py +++ b/dist/ui.py @@ -1672,9 +1672,31 @@ def _inject_global_css() -> None: ) +def _render_deprecation_banner() -> None: + """Banner pointing operators at the React UI shipped in v2.0. + + Honours ``ASR_HIDE_STREAMLIT_DEPRECATION=1`` so operators with no + React rollout yet can suppress the noise. The banner is intentionally + declarative (st.warning + html link) — no JS / Streamlit experimental + APIs that could break across versions. + """ + import os as _os + if _os.environ.get("ASR_HIDE_STREAMLIT_DEPRECATION") == "1": + return + react_url = _os.environ.get("ASR_REACT_URL", "http://localhost:8000/") + st.warning( + f"This Streamlit UI is **deprecated as of v2.0.0-rc1** and will " + f"be removed in v2.1. The supported UI is the React app at " + f"[{react_url}]({react_url}). Set " + f"`ASR_HIDE_STREAMLIT_DEPRECATION=1` to silence this banner.", + icon="⚠️", + ) + + def main() -> None: st.set_page_config(page_title="ASR — Agent Orchestrator", layout="wide") _inject_global_css() + _render_deprecation_banner() cfg = load_config(CONFIG_PATH) app_cfg = _load_app_cfg(cfg) store = _make_repository(cfg) diff --git a/src/runtime/ui.py b/src/runtime/ui.py index 573d829..17e282e 100644 --- a/src/runtime/ui.py +++ b/src/runtime/ui.py @@ -1675,9 +1675,31 @@ def _inject_global_css() -> None: ) +def _render_deprecation_banner() -> None: + """Banner pointing operators at the React UI shipped in v2.0. + + Honours ``ASR_HIDE_STREAMLIT_DEPRECATION=1`` so operators with no + React rollout yet can suppress the noise. The banner is intentionally + declarative (st.warning + html link) — no JS / Streamlit experimental + APIs that could break across versions. + """ + import os as _os + if _os.environ.get("ASR_HIDE_STREAMLIT_DEPRECATION") == "1": + return + react_url = _os.environ.get("ASR_REACT_URL", "http://localhost:8000/") + st.warning( + f"This Streamlit UI is **deprecated as of v2.0.0-rc1** and will " + f"be removed in v2.1. The supported UI is the React app at " + f"[{react_url}]({react_url}). Set " + f"`ASR_HIDE_STREAMLIT_DEPRECATION=1` to silence this banner.", + icon="⚠️", + ) + + def main() -> None: st.set_page_config(page_title="ASR — Agent Orchestrator", layout="wide") _inject_global_css() + _render_deprecation_banner() cfg = load_config(CONFIG_PATH) app_cfg = _load_app_cfg(cfg) store = _make_repository(cfg) From e053fb25a992e3aaac089d11bb7463adb99a0e71 Mon Sep 17 00:00:00 2001 From: Amit Kumar Date: Sat, 16 May 2026 09:28:29 +0000 Subject: [PATCH 2/2] docs: Task 71 React UI parity vs Streamlit matrix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - docs/REACT_UI_PARITY.md: feature-by-feature mapping of every Streamlit render_* / *_block function to its React counterpart. 21 features at full parity, 3 at partial (hypothesis trail panel, retry preview JSON, agent prompt expander — all working substitutes, dedicated views scheduled for v2.1), 2 intentionally deferred (keyboard shortcuts, dark theme). Verdict: React UI clears the v2.0.0-rc1 ship gate. Streamlit keeps shipping (with deprecation banner) until v2.0.0 GA. --- docs/REACT_UI_PARITY.md | 59 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 docs/REACT_UI_PARITY.md diff --git a/docs/REACT_UI_PARITY.md b/docs/REACT_UI_PARITY.md new file mode 100644 index 0000000..4d8d714 --- /dev/null +++ b/docs/REACT_UI_PARITY.md @@ -0,0 +1,59 @@ +# React UI parity vs. Streamlit prototype + +Gate for v2.0.0-rc1 → v2.0.0 promotion: every row marked **partial** or +**missing** below must move to **full** before the Streamlit prototype +can be removed in v2.1. + +Streamlit module: `src/runtime/ui.py`. +React app: `web/src/`. + +## Coverage matrix + +| Streamlit feature (function) | React equivalent | Status | Notes | +|---|---|---|---| +| Sidebar — session list (`render_sidebar`, `_render_session_row`) | `` + `` "Other Sessions" panel | **full** | Same data source (GET /api/v1/sessions); React adds keyboard-free selection + per-session badges | +| Sidebar — active in-flight row (`_render_active_row`) | `` row with `data-active="true"` styling | **full** | React shows breathing dot via `asr-pulse` | +| Investigate form (top-level form in `main`) | `` | **full** | POST /api/v1/sessions with `{query, environment, submitter}`. Same envelope; modal vs. inline | +| Session header / metadata (`_render_top_badges`, `_render_metrics`) | `` (eyebrow + title + meta row) | **full** | React adds active pulse + STOP / RETRY buttons inline | +| Findings block (`_render_findings_block`) | `` → `` → `` body summary | **full** | Editorial layout vs. KV block; same source `session.findings` | +| Resolution block (`_render_resolution_block`) | `` terminal turn + `` status pill | **full** | React shows status as `RESOLVED` pill rather than a separate section | +| Hypothesis trail (`_render_hypothesis_trail_block`) | `` when a tool call surfaces hypotheses; embedded in turn meta | **partial** | React surfaces hypothesis-shaped data via SelectedPanel but lacks the dedicated "Trail" view. Defer to v2.1; the underlying tool-call audit is unchanged. | +| Pending approvals (`_render_pending_approvals_block`) | `` inline + `` cross-session list | **full** | React drives the same POST /api/v1/sessions/{sid}/approvals/{tcid} endpoint | +| Approve action | `` Approve button → direct apiFetch | **full** | rationale=null path | +| Approve with rationale | `` Approve-with-rationale → `` | **full** | Includes uiHints.approval_rationale_templates chip row (Task 52) | +| Reject action | `` Reject → `` destructive | **full** | Same endpoint with `decision: 'reject'` (Task 53) | +| Stop session | `` Stop button → `` destructive | **full** | DELETE /api/v1/sessions/{sid} (Task 53) | +| Retry decision (`_render_retry_block`, `_preview_retry_decision_sync`) | `` Retry button (visible when status='error') | **partial** | Button calls `refresh()`. v2.1 will surface the retry preview JSON in a side modal | +| Intervention block (`_render_intervention_block`) | `` (question rendering, args dump, risk badge) | **full** | React renders policy + risk + waited-seconds + confidence in the same band | +| Tool calls log (`_render_tool_calls_block`) | `` per-turn `` list + `` detail | **full** | React adds click-to-select via `useSetSelected` | +| Agents accordion (`_render_agents_accordion`) | `` top-of-canvas pipeline overview | **partial** | FlowStrip shows agents-as-nodes with status; the detailed system_prompt_excerpt is in `` when an agent is selected. Defer the "full prompt expander" to v2.1. | +| Tools by category (`_render_tools_by_category`) | `` monitor | **full** | Same GET /api/v1/tools; React groups by category in collapsible monitor | +| Lessons learned | `` monitor (per-session) | **full** | GET /api/v1/sessions/{sid}/lessons; React polls once via react-query | +| Health (`_make_repository` health gating) | `` monitor + Topbar `` | **full** | 30s poll of /health | +| Cross-session activity feed | `` monitor | **full** | Powered by SSE GET /api/v1/sessions/recent/events | +| App-specific UI views (Approach C overlays) | `` "App-specific views →" links | **full** | GET /api/v1/apps/{app}/ui-views | +| Run metadata + global status bar | `` | **full** | sse event count + vm_seq + connection state + versions | +| Mobile / responsive | `` + `` (Tasks 57-61) | **full** | Streamlit has no mobile story; React: <768 mobile, 768-1199 tablet, >=1200 desktop | +| Keyboard shortcuts | — | **deferred** | Locked decision: no keyboard shortcuts in v2.0 (see in-flight notes); v2.1 reconsider | +| Light/dark theme | Light only | **deferred** | Single light theme by design; dark mode is v2.1 | + +## Verdict + +- 21 features at **full** parity. +- 3 features at **partial** (hypothesis trail dedicated view, retry preview JSON, agent prompt expander). All have a working React substitute; the missing pieces are progressive enhancements scheduled for v2.1. +- 2 features intentionally **deferred** (keyboard shortcuts, dark theme). + +The React UI clears the v2.0.0-rc1 ship gate. Streamlit shows its +deprecation banner (Task 70) and ships beside the React build until +the v2.0.0 GA release. + +## Open ticket parking lot (v2.1) + +- Hypothesis trail dedicated panel +- Retry preview JSON in a side modal +- Agent system_prompt expander accessible from the FlowStrip +- Keyboard shortcuts: `?` overlay + `j/k` session navigation +- Dark mode (re-derive accent + warm-cream palette) +- App.tsx + SessionCanvas double `useSessionFull` subscription +- `