v0.2.0 feat: operations-console UI + structured escalation/denial signals#2
Merged
Conversation
…phoenix_url run_turn now captures the typed EscalationSummary and any permission_denied tool responses from the ADK event stream (new app/turn_signals.py, pure + unit-tested) and returns them on ChatResponse, so the UI can render escalation and policy cards from real data instead of parsing free text. Adds a phoenix_public_url setting exposed via /config. Fully additive and backward-compatible. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…29, pre-login Ports the design pass into the live UI: slate/paper design system, the monospace receipt strip (tools_used + trace_id), escalation / policy / rate-limit cards driven by the new response fields, pre-login + session-loading screens, a role identity dot, and a working 429 cooldown (a real bug in the old UI). Pure helpers live in ui/lib.js, unit-tested with node --test. Adds a labelled /static/demo.html showcase. Fixes the [hidden]-vs-display bug so the traces pill links to Phoenix and the empty state hides after the first turn. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…mp 0.2.0 README gains a Further enhancements roadmap and a demo-page pointer. architecture.md now carries the full container + chat-turn sequence mermaid diagrams (validated to render error-free via mermaid-cli). Refreshes the chat screenshot to the new UI. Bumps version 0.1.1 -> 0.2.0 (additive feature work). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- runtime: drop the session-state escalation fallback. It could surface a prior
turn's escalation (a different customer) when a later same-session escalation
ran but its summarise step failed; reduce_signals is the sole, live-verified
path now, degrading to a plain reply rather than showing stale data.
- ui: rename .risk-med -> .risk-medium so a Medium risk badge is styled (app.js
generates risk-${level.toLowerCase()} from the enum).
- ui: render an honest error turn on non-OK HTTP (500/422) instead of an empty
"(no reply)" bubble.
- ui: assign the cooldown interval before the first tick so a Retry-After of 0
leaves no orphan interval.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
udtrad
added a commit
that referenced
this pull request
Jul 25, 2026
Aligns uv.lock with the 0.2.0 bump from #2. No dependency changes. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What & why
Implements the EntAssistant UI/UX design pass into the live app, to a production bar. The
backend was already shipped and verified; this PR brings the "operations console" design into
ui/, adds the small backend support the design's cards need, and refreshes the docs.Changes
Backend (additive, backward-compatible)
app/turn_signals.py: pure, unit-tested parsers that pull the typedEscalationSummaryand any
permission_deniedtool responses out of the ADK event stream.run_turncaptures those signals (with asession.statefallback);ChatResponsegainsoptional
escalationanddenialsfields.phoenix_public_urlsetting, exposed via/configfor the header "traces" link.Frontend (operations-console redesign)
tools_used+trace_id) underevery agent reply.
(risk or missing-info badge), amber policy card (RBAC denial), blue-grey rate-limit card.
old UI — it rendered
(no reply)on a rate-limit).ui/lib.js, unit-tested withnode --test./static/demo.html.hiddenattribute was overridden bydisplay:flex, which left the "traces"pill a dead link (opened a new tab to the login screen) and kept the empty-state visible after
the first turn. A global
[hidden]{display:none!important}reset fixes both; the pill nowlinks to Phoenix.
Docs
Further enhancementsroadmap + demo-page pointer.docs/architecture.md: full container + chat-turn sequence mermaid diagrams (validated torender error-free).
Verification (evidence)
make check: 64 passed, 95.85% coverage (ruff + mypy strict clean).node --test ui/tests/: 15/15.mermaid-cli(exit 0).escalationobject and the card rendered; a sales user hitdenials(policy path); the fullKeycloak PKCE login flow rendered the escalation card in the real app.
Notes
0.1.1->0.2.0.Highrisk via the API andNeeds more informationvia the UI on separate runs — both are correct renderings).parseRetryAfter/classifyResponse) but not live-triggered.🤖 Generated with Claude Code