Skip to content

feat(webui): polish agent output and app discovery - #4963

Merged
Re-bin merged 1 commit into
mainfrom
codex/webui-activity-surfaces
Jul 22, 2026
Merged

Re-bin merged 1 commit into
mainfrom
codex/webui-activity-surfaces

Conversation

@Re-bin

@Re-bin Re-bin commented Jul 17, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

  • replace raw, nested tool logs with a unified one-line activity language across reasoning, web, shell, files, memory, apps, MCP, images, subagents, automations, goals, and unknown plugin tools
  • move streamed answers to Streamdown with resilient partial-Markdown repair, subtle native reveal animation, stable completed rendering, and accessible structured content
  • make Apps discovery visually stable and cheaper to render without bundling third-party brand artwork
  • add selected-answer follow-ups: highlight an assistant excerpt, send it to the composer, and pass it to the model as bounded, model-only runtime context
  • tighten mobile interaction, background polling, long-thread rendering, remote assets, and development-mode stability

Activity behavior

  • every default activity item is one line: action, useful target, and status
  • reasoning is summarized inline instead of rendering a short heading with an indented paragraph
  • web searches remain one row while fetched pages render as independent favicon, title, and compact URL rows
  • CLI and MCP actions use product names and human verbs instead of raw function names or JSON
  • repetitive file, search, read, and memory operations are grouped without losing useful state
  • unknown plugin tools fall back to a safe human-readable action without exposing arguments
  • truncated activity rows expose the full value on hover

Streamed Markdown

  • Streamdown renders provider updates directly without a second UI timer or artificial text batching
  • incomplete emphasis, links, fenced code, tables, and other partial Markdown remain readable while tokens arrive
  • Streamdown's native word reveal replaces the custom per-character DOM transformer, including for long CJK answers
  • syntax highlighting is deferred until streaming completes, reducing work on every provider delta
  • a healthy renderer stays mounted when a response changes from streaming to complete; the error boundary still recovers on phase changes after a real failure
  • completed answers contain no leftover animation wrappers
  • tables have deliberate surrounding space, horizontal scrolling, keyboard focus, an accessible region label, and reduced-motion support
  • existing code blocks, math, task lists, file references, previews, attachments, and safe HTML remain supported

Apps and performance

  • deterministic initials render immediately before any remote logo is decoded
  • remote logos and favicons load lazily, fade in only after decode, use no-referrer requests, and retain local fallbacks
  • resolved and failed app logo URLs are cached for the browser session
  • repository-host favicons remain distinct app initials instead of showing one GitHub mark for unrelated tools
  • offscreen catalog rows and completed history defer layout and paint with content-visibility
  • completed thread units are memoized so history does not rerender for every streamed token
  • hidden-tab stream deltas are coalesced and polling/timers pause while the page is hidden
  • Settings and secondary surfaces remain lazy-loaded and preload on user intent
  • syntax highlighting stays Vite-prebundled so Refractor's CommonJS core does not crash the development WebUI

Selected-answer follow-up

  • selecting text in one completed assistant answer offers a compact “Ask about this” action
  • the action is clamped to the visual viewport and dismisses safely on scroll, resize, keyboard movement, or outside interaction
  • the composer shows the selected excerpt before the user sends the follow-up
  • only trusted WebUI envelopes can project quoted_context; ordinary WebSocket clients cannot inject it
  • excerpts are bounded, control characters are normalized, runtime-context markers are escaped, and the context is excluded from public session history
  • AgentLoop consumes a generic internal runtime-context block rather than depending on WebUI-specific metadata

Safety and compatibility

  • credentials, authorization values, API keys, tokens, passwords, URL user credentials, and common provider secret formats are redacted from activity presentation
  • absolute home paths and internal tool-result artifact paths are compacted
  • private or local addresses are not exposed as clickable timeline targets
  • link destinations remain functional while visible labels omit query noise
  • existing channel, provider, tool, config, session, CLI, and gateway behavior is unchanged when the new optional WebUI quote field is absent
  • the new quote field is additive and model-only; it is neither persisted in visible history nor accepted from non-WebUI WebSocket messages

Code structure

  • activity sanitization, trace semantics, reasoning previews, URL safety, page visibility, and remote-logo state live in small focused modules/hooks
  • live and completed events use the same presentation model
  • streaming and completed Markdown remain behind the existing MarkdownText boundary
  • channel-produced runtime context is normalized at the gateway boundary and consumed through a generic agent-core interface
  • the final cleanup removes more custom streaming-renderer code than it adds

Scope

The product work is centered on the React WebUI. A narrow additive gateway/agent bridge supports selected-answer follow-ups by projecting trusted WebUI quotes into bounded runtime context. It does not change default agent execution, model/provider behavior, persisted config, existing channel setup, or CLI commands.

Licensing

  • Streamdown 2.5.0 is Apache-2.0 licensed.
  • no third-party brand SVGs are added to the repository, WebUI bundle, or Python wheel; remote logos remain optional presentation data with local text fallbacks
  • product names, remote logos, and brands remain property of their respective owners and are used only for identification
  • the implementation uses nanobot's own components and data model; it does not redistribute paid AIcss component source or assets

Verification

  • synced with current origin/main
  • full WebUI suite: 48 files, 688 tests passed
  • focused gateway/agent runtime-context suite: 230 tests passed
  • ESLint: passed with zero warnings
  • Ruff across nanobot and tests: passed
  • production TypeScript/Vite build: passed
  • git diff whitespace check: passed
  • browser smoke: long streamed Markdown, lists, blockquotes, tables, links, and activity rows rendered with zero console errors
  • browser regression: fixed the dev-only Refractor/CommonJS crash that unit and production-build checks did not expose
  • full local Python suite: 5,158 passed and 17 skipped; two workspace-scope tests could not invoke bare python under their deliberately restricted PATH on the local macOS runner

@Re-bin
Re-bin force-pushed the codex/webui-activity-surfaces branch from 3eca099 to 2bef80c Compare July 22, 2026 14:36
@Re-bin
Re-bin merged commit aa8387f into main Jul 22, 2026
5 checks passed
@Re-bin
Re-bin deleted the codex/webui-activity-surfaces branch July 22, 2026 14:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants