Skip to content

feat(ui): re-skin the chat experience (stacked on #331, #332)#333

Open
Manushpm8 wants to merge 13 commits into
NVIDIA-AI-Blueprints:developfrom
Manushpm8:feat/ui-chat-look
Open

feat(ui): re-skin the chat experience (stacked on #331, #332)#333
Manushpm8 wants to merge 13 commits into
NVIDIA-AI-Blueprints:developfrom
Manushpm8:feat/ui-chat-look

Conversation

@Manushpm8

@Manushpm8 Manushpm8 commented Jul 14, 2026

Copy link
Copy Markdown

Stacked on #331 and #332. Until those merge, the "Files changed" view here also includes their files. Review this PR by its own commit (feat(ui): re-skin the chat experience) or the Commits tab.

What this does

PR 3 (final) of the UI-only chat port: brings the chat experience to the premium layout. Verified in a browser against a live agent.

  • Live thinking trace (ChatThinking): the intermediate stream folds into a phased spine with status dots, real durations, human tool-call rows, a response timer, and a "using" source chip. Collapses to a summary when done.
  • Answers (AgentResponse): superscript citations with hover popovers, a styled source list, a copy button, and an answer-reveal animation.
  • Interactive clarifier (AgentPrompt): collapsible, with plan approve/reject, clickable options, keyboard shortcuts, and inline free-text.
  • Layout: push-style panels, turn grouping with a run lane and pinned-to-bottom autoscroll, a restyled composer with a stop control, an AppBar theme toggle and active data-source state, a collapsible sessions rail, and re-skinned research/data-source panels and cards.

Preserved (no regression)

Per-user MCP OAuth, human-in-the-loop navigation blocking, and rich artifact/file handling are all kept. The model picker is intentionally omitted (prod exposes no selectable models). No predictive/analytical/warehouse UI is ported.

Testing

  • Full frontend suite green (1487 tests); type-check and lint clean (0 errors).
  • Verified end to end in a browser against a live agent: the composer, the phased thinking trace, and answers with superscript citations + styled source list all render as intended.

Screenshots

The chat on the restored aiq-rfm theme (composer, push panels, NVIDIA Sans base font), and a response summary with the model badge removed (there is no model selector, so the model icon/name is no longer shown next to the timer):

Chat landing on the aiq-rfm palette

Response summary and answer, no model badge

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added interactive clarification and plan-approval prompts with keyboard shortcuts, cancellation, and collapsible previews.
    • Introduced clearer research step timelines, status indicators, source chips, generated-file sections, and auto-following streamed content.
    • Added Markdown enhancements for math, Mermaid diagrams, inline citations, references, and richer answer formatting.
    • Added copy-answer controls, stop-generation action, prompt drafts, model selection, and light/dark theme switching.
    • Redesigned session and data-source panels with collapsible navigation and improved labeling.
  • Bug Fixes

    • Improved report loading errors, retry behavior, deep-research recovery, message ordering, and thinking-step failure handling.

Manushpm8 and others added 2 commits July 14, 2026 02:09
Foundational frontend utilities for the staged chat UI/UX work:
- cn(): clsx + tailwind-merge className composition so conflicting Tailwind
  utilities resolve deterministically.
- titleCaseWords()/ACRONYMS: humanize snake_case and `__`-separated identifiers
  (tool and function names) into display labels, upper-casing common acronyms.
- AppMotionConfig: a Motion provider that honors prefers-reduced-motion.

Adds clsx, tailwind-merge, and motion. Covered 100% by unit tests; no UI
behavior changes yet.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Manush Maheshwari <manushm@nvidia.com>
Adds the UI-only shared component library the chat redesign builds on:
- Sources/*: source chips, list, and reference parsing (web + doc kinds).
- research/*: StatusDot, ToolCallRow, and a generic tool-label engine for the
  live research trace.
- Surface/Card, Actions/CopyButton, CollapsibleBlock, Mermaid.
- MarkdownRenderer upgrade: an answer variant, superscript citations with hover
  popovers, KaTeX math, and Mermaid diagrams. Prod's artifact-URL handling is
  preserved verbatim; chart fences fall through unchanged.

Adds mermaid, katex, rehype-katex, remark-math, unist-util-visit. No
warehouse/predictive features are ported. Covered by unit and render tests.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Manush Maheshwari <manushm@nvidia.com>
@copy-pr-bot

copy-pr-bot Bot commented Jul 14, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@coderabbitai

coderabbitai Bot commented Jul 14, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

This PR introduces interactive clarification and plan-approval prompts, phased research traces, citation-aware Markdown and Mermaid rendering, responsive chat/panel layouts, selected-model persistence, composer controls, source utilities, and extensive supporting tests and styling.

Changes

Chat and research UI

Layer / File(s) Summary
Shared rendering and UI foundation
frontends/ui/src/shared/*, frontends/ui/package.json
Adds citation/source models and components, Markdown math and citation handling, Mermaid rendering, motion configuration, reusable cards, status rows, formatting helpers, and scroll utilities.
Prompt and research trace flow
frontends/ui/src/features/chat/components/AgentPrompt.tsx, ChatThinking.tsx, frontends/ui/src/features/chat/lib/*
Adds interactive clarifier and approval prompts, phased thinking traces, folded-step parsing, and deep-research trace conversion.
Chat state and streaming transport
frontends/ui/src/features/chat/store.ts, types.ts, hooks/use-websocket-chat.ts, adapters/api/websocket-client.ts
Persists selected models, adds thinking-step failure/completion metadata, hydrates deep-research state, and forwards model and intermediate-step status through WebSocket messages.
Chat turns, responses, and composer
frontends/ui/src/features/layout/components/ChatArea.tsx, frontends/ui/src/features/chat/components/AgentResponse.tsx, InputArea.tsx
Groups messages into assistant lanes, adds pinned auto-follow scrolling, renders extracted sources, supports answer variants, restores prompt drafts, and adds stop-generation controls.
Responsive application shell
frontends/ui/src/features/layout/components/MainLayout.tsx, SessionsPanel.tsx, AppBar.tsx, frontends/ui/src/features/layout/store.ts
Changes panels to in-flow layout, adds collapsible session navigation, session recency ordering, theme switching, authentication loading state, and composer state management.
Research panels and task views
frontends/ui/src/features/layout/components/{DataSourcesPanel,ThinkingTab,AgentsTab,ReportTab,ResearchPanel}.tsx
Reworks data-source and research panels, unifies research steps, adds source filtering and generated-file disclosures, and strengthens cancellation fallback handling.
Visual tokens and supporting cleanup
frontends/ui/src/app/globals.css, frontends/ui/src/features/layout/components/*
Adds theme tokens, chat and agent animations, answer typography, reduced-motion rules, composer surfaces, and presentation updates across existing cards and banners.

Estimated code review effort: 5 (Critical) | ~120 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning It covers the change, testing, and screenshots, but misses the required template headings and DCO sign-off details. Rewrite it to match the template: Overview, exact DCO sign-off, Validation checklist, reviewer start point, and related issues.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title uses Conventional Commits and accurately summarizes the chat UI reskin.
Docstring Coverage ✅ Passed Docstring coverage is 85.71% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 Biome (2.5.3)
frontends/ui/src/app/globals.css

File contains syntax errors that prevent linting: Line 189: Tailwind-specific syntax is disabled.; Line 202: Tailwind-specific syntax is disabled.; Line 206: Tailwind-specific syntax is disabled.; Line 210: Tailwind-specific syntax is disabled.; Line 214: Tailwind-specific syntax is disabled.; Line 218: Tailwind-specific syntax is disabled.; Line 222: Tailwind-specific syntax is disabled.; Line 226: Tailwind-specific syntax is disabled.; Line 230: Tailwind-specific syntax is disabled.; Line 234: Tailwind-specific syntax is disabled.; Line 242: Tailwind-specific syntax is disabled.; Line 246: Tailwind-specific syntax is disabled.; Line 250: Tailwind-specific syntax is disabled.; Line 254: Tailwind-specific syntax is disabled.; Line 259: Tailwind-specific syntax is disabled.; Line 265: Tailwind-specific syntax is disabled.; Line 269: Tailwind-specific syntax is disabled.; Line 273: Tailwind-specific syntax is disabled.; Line 281: Tailwind-specific syntax is disabled.; Line 285: Tailwind-specific syntax is disabled.; Line 289: Tailwind-specific syntax is disabled.; Line 293: Tailwind-specific syntax is disabled.; Line 297: Tailwind-specific syntax is disabled.; Line 301: Tailwind-specific syntax is disabled.; Line 305: Tailwind-specific syntax is disabled.; Line 309: Tailwind-specific syntax is disabled.; Line 313: Tailwind-specific syntax is disabled.; Line 317: Tailwind-specific syntax is disabled.


Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 27

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@frontends/ui/package.json`:
- Around line 33-36: Update the dependency versions in the package manifest so
react and react-dom target React 19, matching next@^16.2.6; if TypeScript React
type dependencies are present, align `@types/react` and `@types/react-dom` with
React 19 as well.

In `@frontends/ui/src/app/globals.css`:
- Line 360: Rename the keyframes dotBreathe, assistantTurnIn, thinkingDot,
thinkSweep, and answerBlockReveal to kebab-case in their `@keyframes`
declarations, then update every corresponding animation reference throughout
globals.css so each usage matches its renamed keyframe.
- Around line 510-521: Update the reduced-motion handling in globals.css for
both .thinking-dots > span (thinkingDot) and .thinking-progress::after
(thinkSweep), adding a prefers-reduced-motion: reduce override consistent with
the existing animation overrides in the file. Ensure both infinite decorative
animations are disabled or otherwise made non-animating when reduced motion is
requested.
- Line 670: Replace the deprecated word-break: break-word declaration with
overflow-wrap: anywhere in the affected style rule, adding word-break: normal or
line-break: strict only if needed to preserve the existing wrapping behavior.

In `@frontends/ui/src/features/chat/components/AgentPrompt.tsx`:
- Line 193: Update the approved-state calculation in AgentPrompt so approval
requires an actual non-empty response: retain the rejection check, but do not
treat missing or empty response values as approved. Preserve the existing
behavior for explicit approval and rejection responses.

In `@frontends/ui/src/features/chat/components/AgentResponse.tsx`:
- Around line 149-158: Update the report button flow around handleViewReport and
reportButton so loadResearchPanelTab failures render an existing KUI error
treatment with role="alert" instead of only placing the error in the title. Keep
the button disabled while loading, disable or preserve the appropriate retry
behavior after failure, and add interaction-test coverage for the failed load
and retry state.

In `@frontends/ui/src/features/chat/lib/deep-research-trace.ts`:
- Around line 129-132: Update the tool-call filtering logic in the
trace-building flow so calls with an unknown or dangling agentId are retained
through the “no owning agent” fallback, rather than only accepting calls where
agentId is absent. Add a regression test covering an unknown agentId and verify
the call is included in the generated steps.

In `@frontends/ui/src/features/chat/lib/intermediate-step-parser.ts`:
- Around line 193-199: Update getToolLabel and its caller around the
intermediate-step parser to return an explicit mapping-status indicator, such as
matched or isFallback, alongside the label. Replace the string comparison
against titleCaseWords(cleaned) with that indicator, while preserving the
existing mapped-label and generic title-casing behavior.
- Around line 181-190: Extend titleCaseWords in
frontends/ui/src/shared/lib/humanize.ts:16-26 with an optional case-preservation
parameter so acronym words remain uppercase while non-acronym words can retain
their original casing. In
frontends/ui/src/features/chat/lib/intermediate-step-parser.ts:181-190, replace
the inline acronym-mapping logic with titleCaseWords configured for case
preservation, preserving the existing hyphen splitting and joining behavior.

In `@frontends/ui/src/features/chat/store.ts`:
- Around line 2406-2418: Restrict hydrateDeepResearchFromMessage to
conversations owned by currentUserId before findInConversation inspects messages
or hydration data. Update the fallback over conversations to exclude other
users’ conversations while preserving the current-conversation lookup, and add a
regression test proving cross-user persisted conversations are not hydrated.

In `@frontends/ui/src/features/layout/components/AgentCard.tsx`:
- Around line 68-79: The dedupeToolCalls function currently collapses distinct
unrecognized inputs and fails to replace running calls with error results. Make
the deduplication key uniquely represent unknown inputs, and update replacement
logic so a newer terminal error or complete call supersedes a non-terminal
existing call while preserving the established status behavior. Add tests
covering distinct unknown inputs and a same-argument running-to-error
transition.

In `@frontends/ui/src/features/layout/components/AgentsTab.tsx`:
- Around line 64-68: Update the count badge rendering in AgentsTab to use the
number of top-level deep research thinking steps when runningCount is zero,
rather than deepResearchAgents.length. Reuse deepResearchToThinkingSteps and its
isTopLevel marker so orphan tool calls display an accurate nonzero count while
preserving the existing running-agent count behavior.

In `@frontends/ui/src/features/layout/components/ChatArea.tsx`:
- Line 219: Restore the file-card workflow in ChatArea by implementing
handleFileRetry and reconnecting file message rows to the existing retry,
cancel, and delete handlers. Update the rendering around the file status row and
the handleFileRetry callback so failed and pending files expose actionable
controls, reusing the established file-card components and handlers rather than
leaving inert rows.

In `@frontends/ui/src/features/layout/components/DataConnectionCard.tsx`:
- Around line 133-144: Add tests for the DataConnectionCard/DataConnectionsTab
icon rendering introduced by SourceKindIcon and getDataSourceKind. Cover web and
document sources, and verify the rendered icon styling for enabled and disabled
states, using the existing component test patterns and stable accessible or test
identifiers.

In `@frontends/ui/src/features/layout/components/DataSourcesPanel.spec.tsx`:
- Around line 233-237: Update the closed-state assertion in the DataSourcesPanel
test to target the panel wrapper specifically, rather than any descendant
matching aria-hidden="true". Verify that the wrapper itself has
aria-hidden="true" (and preserve the existing render setup) so decorative icons
cannot satisfy the assertion.

In `@frontends/ui/src/features/layout/components/ReportTab.tsx`:
- Around line 121-147: Bound the expanded generated-files list in ReportTab’s
showFiles rendering so it cannot grow beyond the report panel and hide later
content or the export footer. Apply the existing scroll/overflow styling to the
Flex containing deepResearchFiles.map while preserving the current toggle
behavior and accessible button attributes.

In `@frontends/ui/src/features/layout/components/SessionsPanel.tsx`:
- Around line 201-216: Update closeSearch to restore focus to the “Search
sessions” trigger after closing and unmounting the input, including Escape and
empty-query blur paths. Add or forward a ref through the search trigger’s NavRow
(or use a focusable button) and focus it after setSearchOpen(false), while
preserving the existing query clearing behavior.

In `@frontends/ui/src/shared/components/CollapsibleBlock/CollapsibleBlock.tsx`:
- Around line 36-90: Add a dedicated spec for the CollapsibleBlock component,
covering the collapsible header click invoking onOpenChange with the toggled
value, aria-expanded reflecting open state, and the non-collapsible mode always
rendering children without a header button. Place the tests alongside the
component and exercise the header button versus static div behavior directly.

In `@frontends/ui/src/shared/components/MarkdownRenderer/Citation.spec.tsx`:
- Around line 40-44: Update the non-numeric Citation test to assert that the
visible bracketed fallback text, such as “[NaN]”, is rendered, while retaining
the existing assertions that no link or source chip appears.

In `@frontends/ui/src/shared/components/MarkdownRenderer/Citation.tsx`:
- Around line 31-45: Update the citation control in the component rendering the
`chip` so URL-less sources use a keyboard-focusable button or span instead of an
anchor without `href`, while preserving the anchor behavior for sources with
`src.url`. Keep the existing hover/focus tooltip handlers and accessible
labeling for both variants, and retain link target/rel attributes only when a
URL exists.

In `@frontends/ui/src/shared/components/Mermaid/MermaidBlock.tsx`:
- Around line 183-225: Update the fullscreen branch in the MermaidBlock
component to use the existing KUI modal/dialog component and its
focus-management behavior instead of rendering only a fixed overlay. Ensure
fullscreen is announced as a modal, traps focus within the dialog, restores
focus when closed, supports the existing Escape behavior, and keeps the zoom
controls and Mermaid content inside the dialog.
- Around line 132-148: Update the wheel handler in the MermaidBlock useEffect to
intercept only explicit diagram-zoom gestures, such as wheel events with Ctrl or
Command pressed, while preserving browser-level zoom behavior and normal page
scrolling. Check whether scaling can actually change before calling
preventDefault(), and keep the existing anchor and setScale behavior for valid
zoom events. Ensure the interaction remains accessible and does not block
unrelated scrolling.

In `@frontends/ui/src/shared/components/research/StatusDot.tsx`:
- Around line 15-20: The StatusDot component hides the node state from assistive
technologies without providing an accessible equivalent. Update StatusDot to
include visually hidden text derived from state (running, done, error, etc.)
while keeping the decorative visual dot hidden, so consumers such as ToolCallRow
expose the status to screen readers without requiring additional changes.

In `@frontends/ui/src/shared/components/Sources/parse-references.ts`:
- Around line 125-145: Update renumberOrderedLists so counter resets when a
non-list prose block begins a separate ordered list, not only after headings.
Preserve numbering across nested bullets and other continuation lines, while
allowing an intentional top-level “1.” after prose to remain the start of a new
list.
- Around line 12-13: Unify the references-heading grammar used by
splitReferences and stripTrailingReferences by extracting and reusing a shared
matcher that accepts bold References/Sources and Markdown headings at levels
1–6. Update the splitReferences parsing path to use this matcher so every block
removable by stripTrailingReferences also produces SourceRef entries, and add
coverage for all accepted heading variants.

In `@frontends/ui/src/shared/components/Sources/source-utils.ts`:
- Around line 33-35: Update sourceLabel so prettyDomain is used only for web
sources; for document sources, preserve ref or derive its path basename and fall
back to “Document” when absent. Add regression coverage for nested paths such as
folder/report.pdf and scheme-like document references, ensuring they are not
domain-normalized.

In `@frontends/ui/src/shared/components/Sources/SourceList.tsx`:
- Around line 29-50: Update the source rendering in the sources map to make any
URL-bearing source clickable, including when s.label equals prettyDomain(s.url).
Render s.label itself as the anchor in that case, while preserving the separate
domain link only when it differs from the label; add a regression test covering
a URL source whose label matches its domain.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Enterprise

Run ID: 9a13f411-99bb-435e-b5ff-66effa4d62b1

📥 Commits

Reviewing files that changed from the base of the PR and between e7abd3d and 3c607d3.

⛔ Files ignored due to path filters (1)
  • frontends/ui/package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (114)
  • frontends/ui/package.json
  • frontends/ui/src/adapters/api/websocket-client.ts
  • frontends/ui/src/app/globals.css
  • frontends/ui/src/app/page.tsx
  • frontends/ui/src/app/providers.tsx
  • frontends/ui/src/features/chat/components/AgentPrompt.spec.tsx
  • frontends/ui/src/features/chat/components/AgentPrompt.tsx
  • frontends/ui/src/features/chat/components/AgentResponse.spec.tsx
  • frontends/ui/src/features/chat/components/AgentResponse.tsx
  • frontends/ui/src/features/chat/components/ChatThinking.spec.tsx
  • frontends/ui/src/features/chat/components/ChatThinking.tsx
  • frontends/ui/src/features/chat/components/DeepResearchBanner.tsx
  • frontends/ui/src/features/chat/components/ErrorBanner.tsx
  • frontends/ui/src/features/chat/components/FileUploadBanner.tsx
  • frontends/ui/src/features/chat/components/NoSourcesBanner.tsx
  • frontends/ui/src/features/chat/components/UserMessage.tsx
  • frontends/ui/src/features/chat/components/index.ts
  • frontends/ui/src/features/chat/hooks/use-websocket-chat.ts
  • frontends/ui/src/features/chat/lib/deep-research-trace.spec.ts
  • frontends/ui/src/features/chat/lib/deep-research-trace.ts
  • frontends/ui/src/features/chat/lib/intermediate-step-parser.spec.ts
  • frontends/ui/src/features/chat/lib/intermediate-step-parser.ts
  • frontends/ui/src/features/chat/lib/session-activity.ts
  • frontends/ui/src/features/chat/store.spec.ts
  • frontends/ui/src/features/chat/store.ts
  • frontends/ui/src/features/chat/types.ts
  • frontends/ui/src/features/layout/components/AgentCard.spec.tsx
  • frontends/ui/src/features/layout/components/AgentCard.tsx
  • frontends/ui/src/features/layout/components/AgentsTab.spec.tsx
  • frontends/ui/src/features/layout/components/AgentsTab.tsx
  • frontends/ui/src/features/layout/components/AppBar.spec.tsx
  • frontends/ui/src/features/layout/components/AppBar.tsx
  • frontends/ui/src/features/layout/components/ChatArea.autoscroll.spec.tsx
  • frontends/ui/src/features/layout/components/ChatArea.spec.tsx
  • frontends/ui/src/features/layout/components/ChatArea.tsx
  • frontends/ui/src/features/layout/components/CitationCard.spec.tsx
  • frontends/ui/src/features/layout/components/CitationCard.tsx
  • frontends/ui/src/features/layout/components/DataConnectionCard.tsx
  • frontends/ui/src/features/layout/components/DataConnectionsTab.spec.tsx
  • frontends/ui/src/features/layout/components/DataConnectionsTab.tsx
  • frontends/ui/src/features/layout/components/DataSourcesPanel.spec.tsx
  • frontends/ui/src/features/layout/components/DataSourcesPanel.tsx
  • frontends/ui/src/features/layout/components/FileCard.tsx
  • frontends/ui/src/features/layout/components/FileSourceCard.spec.tsx
  • frontends/ui/src/features/layout/components/FileSourceCard.tsx
  • frontends/ui/src/features/layout/components/FileSourcesTab.spec.tsx
  • frontends/ui/src/features/layout/components/FileSourcesTab.tsx
  • frontends/ui/src/features/layout/components/InputArea.tsx
  • frontends/ui/src/features/layout/components/MainLayout.spec.tsx
  • frontends/ui/src/features/layout/components/MainLayout.tsx
  • frontends/ui/src/features/layout/components/ReportCard.spec.tsx
  • frontends/ui/src/features/layout/components/ReportCard.tsx
  • frontends/ui/src/features/layout/components/ReportTab.tsx
  • frontends/ui/src/features/layout/components/ResearchPanel.spec.tsx
  • frontends/ui/src/features/layout/components/ResearchPanel.tsx
  • frontends/ui/src/features/layout/components/SessionsPanel.spec.tsx
  • frontends/ui/src/features/layout/components/SessionsPanel.tsx
  • frontends/ui/src/features/layout/components/SettingsPanel.spec.tsx
  • frontends/ui/src/features/layout/components/SettingsPanel.tsx
  • frontends/ui/src/features/layout/components/SourceCard.spec.tsx
  • frontends/ui/src/features/layout/components/SourceCard.tsx
  • frontends/ui/src/features/layout/components/TaskCard.spec.tsx
  • frontends/ui/src/features/layout/components/TaskCard.tsx
  • frontends/ui/src/features/layout/components/TasksTab.spec.tsx
  • frontends/ui/src/features/layout/components/TasksTab.tsx
  • frontends/ui/src/features/layout/components/ThinkingTab.spec.tsx
  • frontends/ui/src/features/layout/components/ThinkingTab.tsx
  • frontends/ui/src/features/layout/components/ThoughtCard.spec.tsx
  • frontends/ui/src/features/layout/components/ThoughtCard.tsx
  • frontends/ui/src/features/layout/components/index.ts
  • frontends/ui/src/features/layout/data-sources.spec.ts
  • frontends/ui/src/features/layout/data-sources.ts
  • frontends/ui/src/features/layout/index.ts
  • frontends/ui/src/features/layout/store.spec.ts
  • frontends/ui/src/features/layout/store.ts
  • frontends/ui/src/features/layout/types.ts
  • frontends/ui/src/shared/components/Actions/CopyButton.spec.tsx
  • frontends/ui/src/shared/components/Actions/CopyButton.tsx
  • frontends/ui/src/shared/components/CollapsibleBlock/CollapsibleBlock.tsx
  • frontends/ui/src/shared/components/CollapsibleBlock/index.ts
  • frontends/ui/src/shared/components/MarkdownRenderer/Citation.spec.tsx
  • frontends/ui/src/shared/components/MarkdownRenderer/Citation.tsx
  • frontends/ui/src/shared/components/MarkdownRenderer/MarkdownRenderer.spec.tsx
  • frontends/ui/src/shared/components/MarkdownRenderer/MarkdownRenderer.tsx
  • frontends/ui/src/shared/components/MarkdownRenderer/rehype-citations.spec.ts
  • frontends/ui/src/shared/components/MarkdownRenderer/rehype-citations.ts
  • frontends/ui/src/shared/components/MarkdownRenderer/types.ts
  • frontends/ui/src/shared/components/Mermaid/MermaidBlock.spec.tsx
  • frontends/ui/src/shared/components/Mermaid/MermaidBlock.tsx
  • frontends/ui/src/shared/components/Mermaid/index.ts
  • frontends/ui/src/shared/components/Sources/SourceKindIcon.tsx
  • frontends/ui/src/shared/components/Sources/SourceList.tsx
  • frontends/ui/src/shared/components/Sources/SourceStrip.spec.tsx
  • frontends/ui/src/shared/components/Sources/SourceStrip.tsx
  • frontends/ui/src/shared/components/Sources/parse-references.spec.ts
  • frontends/ui/src/shared/components/Sources/parse-references.ts
  • frontends/ui/src/shared/components/Sources/source-utils.spec.ts
  • frontends/ui/src/shared/components/Sources/source-utils.ts
  • frontends/ui/src/shared/components/Sources/types.ts
  • frontends/ui/src/shared/components/Surface/Card.spec.tsx
  • frontends/ui/src/shared/components/Surface/Card.tsx
  • frontends/ui/src/shared/components/research/StatusDot.tsx
  • frontends/ui/src/shared/components/research/ToolCallRow.tsx
  • frontends/ui/src/shared/components/research/index.ts
  • frontends/ui/src/shared/components/research/research-labels.spec.ts
  • frontends/ui/src/shared/components/research/research-labels.ts
  • frontends/ui/src/shared/lib/cn.spec.ts
  • frontends/ui/src/shared/lib/cn.ts
  • frontends/ui/src/shared/lib/humanize.spec.ts
  • frontends/ui/src/shared/lib/humanize.ts
  • frontends/ui/src/shared/lib/motion.spec.tsx
  • frontends/ui/src/shared/lib/motion.tsx
  • frontends/ui/src/shared/lib/scroll.spec.ts
  • frontends/ui/src/shared/lib/scroll.ts
💤 Files with no reviewable changes (14)
  • frontends/ui/src/features/chat/components/ErrorBanner.tsx
  • frontends/ui/src/features/layout/components/SettingsPanel.spec.tsx
  • frontends/ui/src/features/chat/components/NoSourcesBanner.tsx
  • frontends/ui/src/features/layout/components/DataConnectionsTab.spec.tsx
  • frontends/ui/src/features/chat/components/FileUploadBanner.tsx
  • frontends/ui/src/features/layout/components/ResearchPanel.spec.tsx
  • frontends/ui/src/features/layout/components/ReportCard.spec.tsx
  • frontends/ui/src/features/layout/components/FileSourcesTab.spec.tsx
  • frontends/ui/src/features/chat/components/DeepResearchBanner.tsx
  • frontends/ui/src/features/chat/components/index.ts
  • frontends/ui/src/features/layout/components/TasksTab.spec.tsx
  • frontends/ui/src/features/layout/components/SourceCard.spec.tsx
  • frontends/ui/src/features/layout/components/CitationCard.spec.tsx
  • frontends/ui/src/features/layout/components/index.ts
📜 Review details
🧰 Additional context used
📓 Path-based instructions (3)
frontends/ui/**/*.{js,ts,jsx,tsx,vue}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Run npm lint, type-check, and build validation for UI changes in frontends/ui

Files:

  • frontends/ui/src/shared/lib/cn.ts
  • frontends/ui/src/shared/lib/scroll.spec.ts
  • frontends/ui/src/features/layout/index.ts
  • frontends/ui/src/shared/lib/motion.tsx
  • frontends/ui/src/shared/components/Mermaid/index.ts
  • frontends/ui/src/app/providers.tsx
  • frontends/ui/src/shared/components/research/index.ts
  • frontends/ui/src/shared/components/research/StatusDot.tsx
  • frontends/ui/src/shared/components/research/ToolCallRow.tsx
  • frontends/ui/src/shared/lib/motion.spec.tsx
  • frontends/ui/src/adapters/api/websocket-client.ts
  • frontends/ui/src/shared/components/MarkdownRenderer/types.ts
  • frontends/ui/src/features/layout/data-sources.spec.ts
  • frontends/ui/src/shared/components/CollapsibleBlock/CollapsibleBlock.tsx
  • frontends/ui/src/shared/components/CollapsibleBlock/index.ts
  • frontends/ui/src/shared/components/MarkdownRenderer/rehype-citations.spec.ts
  • frontends/ui/src/features/layout/components/SettingsPanel.tsx
  • frontends/ui/src/shared/lib/cn.spec.ts
  • frontends/ui/src/features/layout/components/FileCard.tsx
  • frontends/ui/src/features/layout/components/TaskCard.tsx
  • frontends/ui/src/shared/components/Sources/SourceList.tsx
  • frontends/ui/src/shared/lib/humanize.spec.ts
  • frontends/ui/src/shared/components/Mermaid/MermaidBlock.spec.tsx
  • frontends/ui/src/app/page.tsx
  • frontends/ui/src/shared/components/Sources/SourceKindIcon.tsx
  • frontends/ui/src/shared/components/MarkdownRenderer/rehype-citations.ts
  • frontends/ui/src/features/layout/components/CitationCard.tsx
  • frontends/ui/src/features/layout/components/DataSourcesPanel.spec.tsx
  • frontends/ui/src/shared/components/research/research-labels.spec.ts
  • frontends/ui/src/shared/lib/humanize.ts
  • frontends/ui/src/shared/components/Sources/source-utils.ts
  • frontends/ui/src/shared/components/Actions/CopyButton.spec.tsx
  • frontends/ui/src/shared/components/Actions/CopyButton.tsx
  • frontends/ui/src/features/layout/store.spec.ts
  • frontends/ui/src/shared/lib/scroll.ts
  • frontends/ui/src/features/chat/lib/session-activity.ts
  • frontends/ui/src/features/chat/components/UserMessage.tsx
  • frontends/ui/src/features/layout/components/DataConnectionCard.tsx
  • frontends/ui/src/shared/components/MarkdownRenderer/Citation.spec.tsx
  • frontends/ui/src/shared/components/MarkdownRenderer/MarkdownRenderer.spec.tsx
  • frontends/ui/src/shared/components/MarkdownRenderer/Citation.tsx
  • frontends/ui/src/features/layout/components/ChatArea.autoscroll.spec.tsx
  • frontends/ui/src/features/layout/components/AgentsTab.tsx
  • frontends/ui/src/shared/components/Sources/source-utils.spec.ts
  • frontends/ui/src/shared/components/Sources/types.ts
  • frontends/ui/src/shared/components/Surface/Card.tsx
  • frontends/ui/src/features/layout/components/DataConnectionsTab.tsx
  • frontends/ui/src/features/layout/components/AgentsTab.spec.tsx
  • frontends/ui/src/features/chat/lib/deep-research-trace.ts
  • frontends/ui/src/shared/components/Surface/Card.spec.tsx
  • frontends/ui/src/shared/components/Sources/parse-references.spec.ts
  • frontends/ui/src/shared/components/Sources/SourceStrip.tsx
  • frontends/ui/src/features/chat/lib/intermediate-step-parser.spec.ts
  • frontends/ui/src/features/chat/store.spec.ts
  • frontends/ui/src/features/layout/components/FileSourceCard.spec.tsx
  • frontends/ui/src/shared/components/Sources/parse-references.ts
  • frontends/ui/src/features/layout/data-sources.ts
  • frontends/ui/src/features/layout/components/TasksTab.tsx
  • frontends/ui/src/shared/components/Mermaid/MermaidBlock.tsx
  • frontends/ui/src/features/layout/components/SourceCard.tsx
  • frontends/ui/src/features/layout/types.ts
  • frontends/ui/src/shared/components/research/research-labels.ts
  • frontends/ui/src/features/chat/types.ts
  • frontends/ui/src/features/layout/components/ThinkingTab.tsx
  • frontends/ui/src/features/layout/components/TaskCard.spec.tsx
  • frontends/ui/src/features/layout/components/ThoughtCard.tsx
  • frontends/ui/src/features/layout/store.ts
  • frontends/ui/src/features/chat/components/AgentResponse.tsx
  • frontends/ui/src/features/chat/components/ChatThinking.spec.tsx
  • frontends/ui/src/features/layout/components/FileSourceCard.tsx
  • frontends/ui/src/features/layout/components/ReportCard.tsx
  • frontends/ui/src/features/layout/components/ReportTab.tsx
  • frontends/ui/src/features/layout/components/ThinkingTab.spec.tsx
  • frontends/ui/src/features/chat/lib/intermediate-step-parser.ts
  • frontends/ui/src/features/chat/hooks/use-websocket-chat.ts
  • frontends/ui/src/features/layout/components/MainLayout.spec.tsx
  • frontends/ui/src/features/layout/components/DataSourcesPanel.tsx
  • frontends/ui/src/features/layout/components/InputArea.tsx
  • frontends/ui/src/features/layout/components/AgentCard.spec.tsx
  • frontends/ui/src/features/chat/lib/deep-research-trace.spec.ts
  • frontends/ui/src/features/layout/components/AgentCard.tsx
  • frontends/ui/src/features/layout/components/MainLayout.tsx
  • frontends/ui/src/shared/components/MarkdownRenderer/MarkdownRenderer.tsx
  • frontends/ui/src/features/chat/components/ChatThinking.tsx
  • frontends/ui/src/features/layout/components/ChatArea.spec.tsx
  • frontends/ui/src/features/chat/components/AgentPrompt.tsx
  • frontends/ui/src/features/chat/components/AgentResponse.spec.tsx
  • frontends/ui/src/features/chat/components/AgentPrompt.spec.tsx
  • frontends/ui/src/features/layout/components/AppBar.tsx
  • frontends/ui/src/features/layout/components/ThoughtCard.spec.tsx
  • frontends/ui/src/shared/components/Sources/SourceStrip.spec.tsx
  • frontends/ui/src/features/layout/components/AppBar.spec.tsx
  • frontends/ui/src/features/layout/components/SessionsPanel.tsx
  • frontends/ui/src/features/layout/components/FileSourcesTab.tsx
  • frontends/ui/src/features/layout/components/SessionsPanel.spec.tsx
  • frontends/ui/src/features/layout/components/ChatArea.tsx
  • frontends/ui/src/features/chat/store.ts
  • frontends/ui/src/features/layout/components/ResearchPanel.tsx
frontends/ui/**/*.{ts,tsx,jsx,js}

📄 CodeRabbit inference engine (AGENTS.md)

frontends/ui/**/*.{ts,tsx,jsx,js}: The UI is built with Next.js / React / TypeScript / Tailwind with KUI components; reuse existing KUI components and visual patterns rather than introducing new ones
Validate UI-affecting changes with npm run lint, npm run type-check, and npm run test:ci, and include a screenshot for visible changes

Files:

  • frontends/ui/src/shared/lib/cn.ts
  • frontends/ui/src/shared/lib/scroll.spec.ts
  • frontends/ui/src/features/layout/index.ts
  • frontends/ui/src/shared/lib/motion.tsx
  • frontends/ui/src/shared/components/Mermaid/index.ts
  • frontends/ui/src/app/providers.tsx
  • frontends/ui/src/shared/components/research/index.ts
  • frontends/ui/src/shared/components/research/StatusDot.tsx
  • frontends/ui/src/shared/components/research/ToolCallRow.tsx
  • frontends/ui/src/shared/lib/motion.spec.tsx
  • frontends/ui/src/adapters/api/websocket-client.ts
  • frontends/ui/src/shared/components/MarkdownRenderer/types.ts
  • frontends/ui/src/features/layout/data-sources.spec.ts
  • frontends/ui/src/shared/components/CollapsibleBlock/CollapsibleBlock.tsx
  • frontends/ui/src/shared/components/CollapsibleBlock/index.ts
  • frontends/ui/src/shared/components/MarkdownRenderer/rehype-citations.spec.ts
  • frontends/ui/src/features/layout/components/SettingsPanel.tsx
  • frontends/ui/src/shared/lib/cn.spec.ts
  • frontends/ui/src/features/layout/components/FileCard.tsx
  • frontends/ui/src/features/layout/components/TaskCard.tsx
  • frontends/ui/src/shared/components/Sources/SourceList.tsx
  • frontends/ui/src/shared/lib/humanize.spec.ts
  • frontends/ui/src/shared/components/Mermaid/MermaidBlock.spec.tsx
  • frontends/ui/src/app/page.tsx
  • frontends/ui/src/shared/components/Sources/SourceKindIcon.tsx
  • frontends/ui/src/shared/components/MarkdownRenderer/rehype-citations.ts
  • frontends/ui/src/features/layout/components/CitationCard.tsx
  • frontends/ui/src/features/layout/components/DataSourcesPanel.spec.tsx
  • frontends/ui/src/shared/components/research/research-labels.spec.ts
  • frontends/ui/src/shared/lib/humanize.ts
  • frontends/ui/src/shared/components/Sources/source-utils.ts
  • frontends/ui/src/shared/components/Actions/CopyButton.spec.tsx
  • frontends/ui/src/shared/components/Actions/CopyButton.tsx
  • frontends/ui/src/features/layout/store.spec.ts
  • frontends/ui/src/shared/lib/scroll.ts
  • frontends/ui/src/features/chat/lib/session-activity.ts
  • frontends/ui/src/features/chat/components/UserMessage.tsx
  • frontends/ui/src/features/layout/components/DataConnectionCard.tsx
  • frontends/ui/src/shared/components/MarkdownRenderer/Citation.spec.tsx
  • frontends/ui/src/shared/components/MarkdownRenderer/MarkdownRenderer.spec.tsx
  • frontends/ui/src/shared/components/MarkdownRenderer/Citation.tsx
  • frontends/ui/src/features/layout/components/ChatArea.autoscroll.spec.tsx
  • frontends/ui/src/features/layout/components/AgentsTab.tsx
  • frontends/ui/src/shared/components/Sources/source-utils.spec.ts
  • frontends/ui/src/shared/components/Sources/types.ts
  • frontends/ui/src/shared/components/Surface/Card.tsx
  • frontends/ui/src/features/layout/components/DataConnectionsTab.tsx
  • frontends/ui/src/features/layout/components/AgentsTab.spec.tsx
  • frontends/ui/src/features/chat/lib/deep-research-trace.ts
  • frontends/ui/src/shared/components/Surface/Card.spec.tsx
  • frontends/ui/src/shared/components/Sources/parse-references.spec.ts
  • frontends/ui/src/shared/components/Sources/SourceStrip.tsx
  • frontends/ui/src/features/chat/lib/intermediate-step-parser.spec.ts
  • frontends/ui/src/features/chat/store.spec.ts
  • frontends/ui/src/features/layout/components/FileSourceCard.spec.tsx
  • frontends/ui/src/shared/components/Sources/parse-references.ts
  • frontends/ui/src/features/layout/data-sources.ts
  • frontends/ui/src/features/layout/components/TasksTab.tsx
  • frontends/ui/src/shared/components/Mermaid/MermaidBlock.tsx
  • frontends/ui/src/features/layout/components/SourceCard.tsx
  • frontends/ui/src/features/layout/types.ts
  • frontends/ui/src/shared/components/research/research-labels.ts
  • frontends/ui/src/features/chat/types.ts
  • frontends/ui/src/features/layout/components/ThinkingTab.tsx
  • frontends/ui/src/features/layout/components/TaskCard.spec.tsx
  • frontends/ui/src/features/layout/components/ThoughtCard.tsx
  • frontends/ui/src/features/layout/store.ts
  • frontends/ui/src/features/chat/components/AgentResponse.tsx
  • frontends/ui/src/features/chat/components/ChatThinking.spec.tsx
  • frontends/ui/src/features/layout/components/FileSourceCard.tsx
  • frontends/ui/src/features/layout/components/ReportCard.tsx
  • frontends/ui/src/features/layout/components/ReportTab.tsx
  • frontends/ui/src/features/layout/components/ThinkingTab.spec.tsx
  • frontends/ui/src/features/chat/lib/intermediate-step-parser.ts
  • frontends/ui/src/features/chat/hooks/use-websocket-chat.ts
  • frontends/ui/src/features/layout/components/MainLayout.spec.tsx
  • frontends/ui/src/features/layout/components/DataSourcesPanel.tsx
  • frontends/ui/src/features/layout/components/InputArea.tsx
  • frontends/ui/src/features/layout/components/AgentCard.spec.tsx
  • frontends/ui/src/features/chat/lib/deep-research-trace.spec.ts
  • frontends/ui/src/features/layout/components/AgentCard.tsx
  • frontends/ui/src/features/layout/components/MainLayout.tsx
  • frontends/ui/src/shared/components/MarkdownRenderer/MarkdownRenderer.tsx
  • frontends/ui/src/features/chat/components/ChatThinking.tsx
  • frontends/ui/src/features/layout/components/ChatArea.spec.tsx
  • frontends/ui/src/features/chat/components/AgentPrompt.tsx
  • frontends/ui/src/features/chat/components/AgentResponse.spec.tsx
  • frontends/ui/src/features/chat/components/AgentPrompt.spec.tsx
  • frontends/ui/src/features/layout/components/AppBar.tsx
  • frontends/ui/src/features/layout/components/ThoughtCard.spec.tsx
  • frontends/ui/src/shared/components/Sources/SourceStrip.spec.tsx
  • frontends/ui/src/features/layout/components/AppBar.spec.tsx
  • frontends/ui/src/features/layout/components/SessionsPanel.tsx
  • frontends/ui/src/features/layout/components/FileSourcesTab.tsx
  • frontends/ui/src/features/layout/components/SessionsPanel.spec.tsx
  • frontends/ui/src/features/layout/components/ChatArea.tsx
  • frontends/ui/src/features/chat/store.ts
  • frontends/ui/src/features/layout/components/ResearchPanel.tsx
frontends/ui/**/*

⚙️ CodeRabbit configuration file

frontends/ui/**/*: Review UI changes for strict TypeScript behavior, API contract alignment, auth/session handling, accessible controls,
resilient loading and error states, and report/chat state consistency. Prefer existing UI patterns and require tests
for changed user-visible workflows.

Files:

  • frontends/ui/src/shared/lib/cn.ts
  • frontends/ui/src/shared/lib/scroll.spec.ts
  • frontends/ui/src/features/layout/index.ts
  • frontends/ui/src/shared/lib/motion.tsx
  • frontends/ui/src/shared/components/Mermaid/index.ts
  • frontends/ui/src/app/providers.tsx
  • frontends/ui/src/shared/components/research/index.ts
  • frontends/ui/src/shared/components/research/StatusDot.tsx
  • frontends/ui/src/shared/components/research/ToolCallRow.tsx
  • frontends/ui/src/shared/lib/motion.spec.tsx
  • frontends/ui/src/adapters/api/websocket-client.ts
  • frontends/ui/src/shared/components/MarkdownRenderer/types.ts
  • frontends/ui/src/features/layout/data-sources.spec.ts
  • frontends/ui/src/shared/components/CollapsibleBlock/CollapsibleBlock.tsx
  • frontends/ui/src/shared/components/CollapsibleBlock/index.ts
  • frontends/ui/src/shared/components/MarkdownRenderer/rehype-citations.spec.ts
  • frontends/ui/src/features/layout/components/SettingsPanel.tsx
  • frontends/ui/src/shared/lib/cn.spec.ts
  • frontends/ui/src/features/layout/components/FileCard.tsx
  • frontends/ui/src/features/layout/components/TaskCard.tsx
  • frontends/ui/src/shared/components/Sources/SourceList.tsx
  • frontends/ui/src/shared/lib/humanize.spec.ts
  • frontends/ui/src/shared/components/Mermaid/MermaidBlock.spec.tsx
  • frontends/ui/src/app/page.tsx
  • frontends/ui/src/shared/components/Sources/SourceKindIcon.tsx
  • frontends/ui/src/shared/components/MarkdownRenderer/rehype-citations.ts
  • frontends/ui/package.json
  • frontends/ui/src/features/layout/components/CitationCard.tsx
  • frontends/ui/src/features/layout/components/DataSourcesPanel.spec.tsx
  • frontends/ui/src/shared/components/research/research-labels.spec.ts
  • frontends/ui/src/shared/lib/humanize.ts
  • frontends/ui/src/shared/components/Sources/source-utils.ts
  • frontends/ui/src/shared/components/Actions/CopyButton.spec.tsx
  • frontends/ui/src/shared/components/Actions/CopyButton.tsx
  • frontends/ui/src/features/layout/store.spec.ts
  • frontends/ui/src/shared/lib/scroll.ts
  • frontends/ui/src/features/chat/lib/session-activity.ts
  • frontends/ui/src/features/chat/components/UserMessage.tsx
  • frontends/ui/src/features/layout/components/DataConnectionCard.tsx
  • frontends/ui/src/shared/components/MarkdownRenderer/Citation.spec.tsx
  • frontends/ui/src/shared/components/MarkdownRenderer/MarkdownRenderer.spec.tsx
  • frontends/ui/src/shared/components/MarkdownRenderer/Citation.tsx
  • frontends/ui/src/features/layout/components/ChatArea.autoscroll.spec.tsx
  • frontends/ui/src/features/layout/components/AgentsTab.tsx
  • frontends/ui/src/shared/components/Sources/source-utils.spec.ts
  • frontends/ui/src/shared/components/Sources/types.ts
  • frontends/ui/src/shared/components/Surface/Card.tsx
  • frontends/ui/src/features/layout/components/DataConnectionsTab.tsx
  • frontends/ui/src/features/layout/components/AgentsTab.spec.tsx
  • frontends/ui/src/features/chat/lib/deep-research-trace.ts
  • frontends/ui/src/shared/components/Surface/Card.spec.tsx
  • frontends/ui/src/shared/components/Sources/parse-references.spec.ts
  • frontends/ui/src/shared/components/Sources/SourceStrip.tsx
  • frontends/ui/src/features/chat/lib/intermediate-step-parser.spec.ts
  • frontends/ui/src/features/chat/store.spec.ts
  • frontends/ui/src/features/layout/components/FileSourceCard.spec.tsx
  • frontends/ui/src/shared/components/Sources/parse-references.ts
  • frontends/ui/src/features/layout/data-sources.ts
  • frontends/ui/src/features/layout/components/TasksTab.tsx
  • frontends/ui/src/shared/components/Mermaid/MermaidBlock.tsx
  • frontends/ui/src/features/layout/components/SourceCard.tsx
  • frontends/ui/src/features/layout/types.ts
  • frontends/ui/src/shared/components/research/research-labels.ts
  • frontends/ui/src/features/chat/types.ts
  • frontends/ui/src/features/layout/components/ThinkingTab.tsx
  • frontends/ui/src/features/layout/components/TaskCard.spec.tsx
  • frontends/ui/src/features/layout/components/ThoughtCard.tsx
  • frontends/ui/src/features/layout/store.ts
  • frontends/ui/src/features/chat/components/AgentResponse.tsx
  • frontends/ui/src/features/chat/components/ChatThinking.spec.tsx
  • frontends/ui/src/features/layout/components/FileSourceCard.tsx
  • frontends/ui/src/features/layout/components/ReportCard.tsx
  • frontends/ui/src/features/layout/components/ReportTab.tsx
  • frontends/ui/src/features/layout/components/ThinkingTab.spec.tsx
  • frontends/ui/src/features/chat/lib/intermediate-step-parser.ts
  • frontends/ui/src/features/chat/hooks/use-websocket-chat.ts
  • frontends/ui/src/features/layout/components/MainLayout.spec.tsx
  • frontends/ui/src/features/layout/components/DataSourcesPanel.tsx
  • frontends/ui/src/features/layout/components/InputArea.tsx
  • frontends/ui/src/features/layout/components/AgentCard.spec.tsx
  • frontends/ui/src/features/chat/lib/deep-research-trace.spec.ts
  • frontends/ui/src/features/layout/components/AgentCard.tsx
  • frontends/ui/src/features/layout/components/MainLayout.tsx
  • frontends/ui/src/shared/components/MarkdownRenderer/MarkdownRenderer.tsx
  • frontends/ui/src/features/chat/components/ChatThinking.tsx
  • frontends/ui/src/features/layout/components/ChatArea.spec.tsx
  • frontends/ui/src/features/chat/components/AgentPrompt.tsx
  • frontends/ui/src/features/chat/components/AgentResponse.spec.tsx
  • frontends/ui/src/features/chat/components/AgentPrompt.spec.tsx
  • frontends/ui/src/features/layout/components/AppBar.tsx
  • frontends/ui/src/features/layout/components/ThoughtCard.spec.tsx
  • frontends/ui/src/shared/components/Sources/SourceStrip.spec.tsx
  • frontends/ui/src/features/layout/components/AppBar.spec.tsx
  • frontends/ui/src/features/layout/components/SessionsPanel.tsx
  • frontends/ui/src/features/layout/components/FileSourcesTab.tsx
  • frontends/ui/src/features/layout/components/SessionsPanel.spec.tsx
  • frontends/ui/src/features/layout/components/ChatArea.tsx
  • frontends/ui/src/features/chat/store.ts
  • frontends/ui/src/features/layout/components/ResearchPanel.tsx
  • frontends/ui/src/app/globals.css
🪛 ast-grep (0.44.1)
frontends/ui/src/shared/components/Mermaid/MermaidBlock.tsx

[warning] 251-251: Usage of dangerouslySetInnerHTML detected. This bypasses React's built-in XSS protection. Always sanitize HTML content using libraries like DOMPurify before injecting it into the DOM to prevent XSS attacks.
Context: dangerouslySetInnerHTML
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation

(react-unsafe-html-injection)

frontends/ui/src/shared/components/research/research-labels.ts

[warning] 167-167: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(["']${escapedKey}["']\\s*:\\s*"((?:\\\\.|[^"\\\\])*)")
Note: [CWE-1333] Inefficient Regular Expression Complexity

(regexp-from-variable)


[warning] 172-172: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(["']${escapedKey}["']\\s*:\\s*'((?:\\\\.|[^'\\\\])*)')
Note: [CWE-1333] Inefficient Regular Expression Complexity

(regexp-from-variable)

🪛 OpenGrep (1.25.0)
frontends/ui/src/shared/components/MarkdownRenderer/rehype-citations.ts

[ERROR] 24-24: Dynamic command passed to child_process.exec/execSync. Use child_process.execFile or spawn with an argument array instead.

(coderabbit.command-injection.exec-js)

frontends/ui/src/shared/components/Mermaid/MermaidBlock.tsx

[WARNING] 243-253: dangerouslySetInnerHTML with dynamic content can lead to XSS. Sanitize the input with a library like DOMPurify before rendering.

(coderabbit.xss.react-dangerously-set-innerhtml)

🪛 Stylelint (17.14.0)
frontends/ui/src/app/globals.css

[error] 670-670: Deprecated keyword "break-word" for property "word-break" (declaration-property-value-keyword-no-deprecated)

(declaration-property-value-keyword-no-deprecated)


[error] 360-360: Expected keyframe name "dotBreathe" to be kebab-case (keyframes-name-pattern)

(keyframes-name-pattern)


[error] 453-453: Expected keyframe name "assistantTurnIn" to be kebab-case (keyframes-name-pattern)

(keyframes-name-pattern)


[error] 522-522: Expected keyframe name "thinkingDot" to be kebab-case (keyframes-name-pattern)

(keyframes-name-pattern)


[error] 596-596: Expected keyframe name "thinkSweep" to be kebab-case (keyframes-name-pattern)

(keyframes-name-pattern)


[error] 745-745: Expected keyframe name "answerBlockReveal" to be kebab-case (keyframes-name-pattern)

(keyframes-name-pattern)

Comment thread frontends/ui/package.json
Comment thread frontends/ui/src/app/globals.css Outdated
Comment thread frontends/ui/src/app/globals.css
Comment thread frontends/ui/src/app/globals.css Outdated
Comment thread frontends/ui/src/features/chat/components/AgentPrompt.tsx Outdated
Comment thread frontends/ui/src/shared/components/research/StatusDot.tsx
Comment thread frontends/ui/src/shared/components/Sources/parse-references.ts
Comment thread frontends/ui/src/shared/components/Sources/parse-references.ts
Comment thread frontends/ui/src/shared/components/Sources/source-utils.ts
Comment thread frontends/ui/src/shared/components/Sources/SourceList.tsx
- rehype-citations: skip [n] markers inside code/pre so code samples like
  arr[1] are not turned into citations.
- CopyButton: track the reset timeout in a ref, clearing it on re-click and
  unmount.
- SourceList: always render a clickable link for URL-bearing sources, including
  when the label equals the domain.
- source-utils: reuse the computed kind instead of re-testing the URL regex.
- CollapsibleBlock: wire aria-controls to the disclosed region id.
- SourceStrip: expose aria-expanded on the "+N more" button.
- Citation: keep URL-less citations keyboard-focusable.
- Add CollapsibleBlock and SourceList unit tests.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Manush Maheshwari <manushm@nvidia.com>
@Manushpm8
Manushpm8 force-pushed the feat/ui-chat-look branch from 3c607d3 to 138aa63 Compare July 14, 2026 17:27

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 13

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (4)
frontends/ui/src/shared/components/CollapsibleBlock/CollapsibleBlock.tsx (1)

62-91: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

aria-controls dangles once the panel unmounts.

AnimatePresence fully removes the motion.div (and its id={regionId}) from the DOM when collapsed, but the button's aria-controls={regionId} is set unconditionally — so while closed, assistive tech is told to control an element that no longer exists.

As per path instructions, "Review UI changes for ... accessible controls."

♿ Proposed fix
-          aria-controls={regionId}
+          aria-controls={open ? regionId : undefined}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontends/ui/src/shared/components/CollapsibleBlock/CollapsibleBlock.tsx`
around lines 62 - 91, Update the collapsible trigger in CollapsibleBlock so
aria-controls is only set while the controlled motion.div is mounted, matching
the (open || !collapsible) rendering condition. Preserve regionId on the panel
and the existing expanded-state behavior.

Source: Path instructions

frontends/ui/src/features/layout/components/AgentCard.tsx (1)

87-176: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Render agent.output in the expandable body
hasExpandableContent only checks currentTask and tool calls, but completeDeepResearchAgent populates AgentInfo.output. A completed agent with no other content stays disabled and its result never appears here; add output to the expandability/content check, or remove it from this card’s contract/tests if it isn’t meant to surface.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontends/ui/src/features/layout/components/AgentCard.tsx` around lines 87 -
176, Update AgentCard’s hasExpandableContent and expandable body to include
agent.output, allowing completed agents with output but no task or tool calls to
expand and display their result. Preserve the existing currentTask and tool-call
rendering, and ensure the expandability, disabled state, and rendered content
use the same output-aware condition.
frontends/ui/src/adapters/api/websocket-client.ts (1)

222-240: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Update JSDoc for the new selectedModel param.

The docstring above sendMessage still lists only the original three params; add @param selectedModel to keep it accurate.

📝 Suggested docstring update
   /**
    * Send a user chat message
    * `@param` content - The message text content (query)
    * `@param` enabledDataSources - Optional array of enabled data source IDs to include in the query
    * `@param` activeReportJobId - Optional completed report job ID for report-aware follow-up
+   * `@param` selectedModel - Optional model identifier to include in the outgoing payload
    */
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontends/ui/src/adapters/api/websocket-client.ts` around lines 222 - 240,
Update the JSDoc above sendMessage to document the selectedModel parameter,
describing it as the optional selected model identifier used for the query.
frontends/ui/src/shared/components/Actions/CopyButton.tsx (1)

44-55: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

"Copied" confirmation may not reach screen-reader users.

The state change is only exposed via aria-label/title. Per accessibility guidance, an accessible-name change on the currently focused element "is not consistently announced" by screen readers without a live region. Consider adding a visually-hidden aria-live="polite" span announcing "Copied to clipboard" alongside the icon swap.

As per path instructions, review UI changes for "accessible controls."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontends/ui/src/shared/components/Actions/CopyButton.tsx` around lines 44 -
55, Add a visually hidden aria-live="polite" announcement alongside the icon in
the CopyButton component, announcing “Copied to clipboard” when copied becomes
true. Keep the existing button label, title, focus behavior, and icon swap
unchanged.

Source: Path instructions

♻️ Duplicate comments (1)
frontends/ui/src/shared/components/MarkdownRenderer/Citation.tsx (1)

32-47: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Keyboard focus restored; consider adding an explicit role for full semantics.

tabIndex={0} fixes the focus-reachability issue from the prior review. For a more robust fix, consider adding role="button" (or rendering a <button>/<span> for the URL-less case, as originally suggested) so assistive tech exposes correct semantics instead of a bare, role-less <a>.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontends/ui/src/shared/components/MarkdownRenderer/Citation.tsx` around
lines 32 - 47, Update the `chip` anchor in `Citation` to expose explicit button
semantics when `src?.url` is absent, such as by adding the appropriate
conditional role while preserving normal link semantics for URL-backed
citations.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@frontends/ui/src/app/globals.css`:
- Around line 983-1001: Replace the !important-based overrides in
.agent-action-approve and .agent-action-reject, including their hover states, by
using the underlying KUI Button’s supported color/kind variant props to achieve
the same text, background, and border styling. Update the button usage rather
than relying on brittle CSS specificity, while preserving the existing approve
and reject visual states.

In `@frontends/ui/src/features/chat/components/AgentPrompt.spec.tsx`:
- Around line 300-317: Update the test for the responded approval prompt with no
response to assert that neither “Plan approved” nor “Plan rejected” is rendered.
Keep the missing response state neutral, and add or update coverage for the
changed user-visible approval workflow as needed.

In `@frontends/ui/src/features/chat/components/AgentResponse.spec.tsx`:
- Around line 163-170: Extend the `surfaces a report-load error as an inline
alert and offers retry` test to click the Retry button and assert that
`mockLoadResearchPanelTab` is called with `job-1` and `report`. Keep the
existing alert text and button-presence assertions.

In `@frontends/ui/src/features/chat/components/ChatThinking.tsx`:
- Around line 375-385: Add stable unique IDs to the controlled content regions
and set matching aria-controls values on the CollapsibleText toggle and PhaseRow
head button alongside their existing aria-expanded attributes. Reuse the
useId-based disclosure pattern from CollapsibleBlock, and ensure each control
references only its own region.
- Around line 213-231: Replace the weighted numeric rank in the
duplicate-selection logic with an explicit lexicographic comparison in the
groups loop: prefer top-level steps, then completed/successful steps, then the
latest index. Update the `rank`/`best` comparison around `enriched` so index
magnitude cannot override either higher-priority criterion, while preserving the
existing grouping and drop behavior.
- Around line 426-477: Update the PhaseRow open state so it re-synchronizes with
defaultOpen whenever the phase state changes from running to done, using the
existing CollapsibleText resync pattern. Preserve manual toggling through the
head button’s click handler while ensuring completed phases collapse
automatically when defaultOpen becomes false.

In `@frontends/ui/src/features/chat/store.spec.ts`:
- Around line 2286-2347: Add a regression test alongside
hydrateDeepResearchFromMessage covering the fallback across multiple
conversations: configure currentUserId as user-1, set currentConversation to an
empty user-1 conversation, include a user-2 conversation containing saved state
for the requested job, and assert hydrateDeepResearchFromMessage returns false
without hydrating that state.

In `@frontends/ui/src/features/layout/components/AgentCard.tsx`:
- Around line 68-81: Update dedupeToolCalls so every duplicate key
unconditionally replaces the existing entry with the latest tool call,
preserving Map iteration order and reflecting terminal-to-terminal status
transitions. Add a regression test in AgentCard.spec.tsx covering an
error-to-complete or complete-to-error same-key transition alongside the
existing running-to-error case.

In `@frontends/ui/src/features/layout/components/AgentsTab.tsx`:
- Around line 46-48: Update the running-state derivation in AgentsTab so it
reflects rendered top-level steps, including orphan tool calls with status
"running", rather than only deepResearchAgents. Keep ChatThinking’s
incomplete-phase state and the header’s “running” indicator consistent with that
derived count, and add coverage for a running orphan tool call.
- Around line 51-56: Update the scrolling useEffect in AgentsTab around
scrollRef, steps.length, and runningCount so it also reacts when existing step
content or status changes, not only when the array length changes. Use the
relevant step data or update signal already available in the component while
preserving the nearBottom check and pinned-scroll behavior.

In `@frontends/ui/src/features/layout/components/ChatArea.tsx`:
- Around line 221-227: Update the chat message container in ChatArea’s returned
Flex element to expose it as an ARIA live log, adding the appropriate role and
live-region attributes while preserving the existing aria-label and scrolling
behavior.

In `@frontends/ui/src/features/layout/components/SessionsPanel.tsx`:
- Around line 700-746: Update groupSessionsByDate to preserve the input sessions
order: remove the ordered copy and date-based sort, then iterate directly over
sessions while retaining the existing bucket grouping and output order. Keep
bucket assignment unchanged so groups and sessions within each group reflect the
caller’s sort order, and add a regression test covering order that differs from
session.date.

In `@frontends/ui/src/features/layout/components/ThinkingTab.tsx`:
- Around line 209-217: Update the expanded generated-files list in ThinkingTab’s
showFiles rendering to apply a bounded maximum height and appropriate overflow
scrolling, matching the equivalent Report view. Preserve the existing
deepResearchFiles mapping and FileCard rendering while ensuring many files
cannot collapse or be clipped by the parent panel.

---

Outside diff comments:
In `@frontends/ui/src/adapters/api/websocket-client.ts`:
- Around line 222-240: Update the JSDoc above sendMessage to document the
selectedModel parameter, describing it as the optional selected model identifier
used for the query.

In `@frontends/ui/src/features/layout/components/AgentCard.tsx`:
- Around line 87-176: Update AgentCard’s hasExpandableContent and expandable
body to include agent.output, allowing completed agents with output but no task
or tool calls to expand and display their result. Preserve the existing
currentTask and tool-call rendering, and ensure the expandability, disabled
state, and rendered content use the same output-aware condition.

In `@frontends/ui/src/shared/components/Actions/CopyButton.tsx`:
- Around line 44-55: Add a visually hidden aria-live="polite" announcement
alongside the icon in the CopyButton component, announcing “Copied to clipboard”
when copied becomes true. Keep the existing button label, title, focus behavior,
and icon swap unchanged.

In `@frontends/ui/src/shared/components/CollapsibleBlock/CollapsibleBlock.tsx`:
- Around line 62-91: Update the collapsible trigger in CollapsibleBlock so
aria-controls is only set while the controlled motion.div is mounted, matching
the (open || !collapsible) rendering condition. Preserve regionId on the panel
and the existing expanded-state behavior.

---

Duplicate comments:
In `@frontends/ui/src/shared/components/MarkdownRenderer/Citation.tsx`:
- Around line 32-47: Update the `chip` anchor in `Citation` to expose explicit
button semantics when `src?.url` is absent, such as by adding the appropriate
conditional role while preserving normal link semantics for URL-backed
citations.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Enterprise

Run ID: 6be407cf-77dd-4806-b614-9bafb8c0c5cb

📥 Commits

Reviewing files that changed from the base of the PR and between 3c607d3 and 138aa63.

📒 Files selected for processing (87)
  • frontends/ui/src/adapters/api/websocket-client.ts
  • frontends/ui/src/app/globals.css
  • frontends/ui/src/app/page.tsx
  • frontends/ui/src/app/providers.tsx
  • frontends/ui/src/features/chat/components/AgentPrompt.spec.tsx
  • frontends/ui/src/features/chat/components/AgentPrompt.tsx
  • frontends/ui/src/features/chat/components/AgentResponse.spec.tsx
  • frontends/ui/src/features/chat/components/AgentResponse.tsx
  • frontends/ui/src/features/chat/components/ChatThinking.spec.tsx
  • frontends/ui/src/features/chat/components/ChatThinking.tsx
  • frontends/ui/src/features/chat/components/DeepResearchBanner.tsx
  • frontends/ui/src/features/chat/components/ErrorBanner.tsx
  • frontends/ui/src/features/chat/components/FileUploadBanner.tsx
  • frontends/ui/src/features/chat/components/NoSourcesBanner.tsx
  • frontends/ui/src/features/chat/components/UserMessage.tsx
  • frontends/ui/src/features/chat/components/index.ts
  • frontends/ui/src/features/chat/hooks/use-websocket-chat.ts
  • frontends/ui/src/features/chat/lib/deep-research-trace.spec.ts
  • frontends/ui/src/features/chat/lib/deep-research-trace.ts
  • frontends/ui/src/features/chat/lib/intermediate-step-parser.spec.ts
  • frontends/ui/src/features/chat/lib/intermediate-step-parser.ts
  • frontends/ui/src/features/chat/lib/session-activity.ts
  • frontends/ui/src/features/chat/store.spec.ts
  • frontends/ui/src/features/chat/store.ts
  • frontends/ui/src/features/chat/types.ts
  • frontends/ui/src/features/layout/components/AgentCard.spec.tsx
  • frontends/ui/src/features/layout/components/AgentCard.tsx
  • frontends/ui/src/features/layout/components/AgentsTab.spec.tsx
  • frontends/ui/src/features/layout/components/AgentsTab.tsx
  • frontends/ui/src/features/layout/components/AppBar.spec.tsx
  • frontends/ui/src/features/layout/components/AppBar.tsx
  • frontends/ui/src/features/layout/components/ChatArea.autoscroll.spec.tsx
  • frontends/ui/src/features/layout/components/ChatArea.spec.tsx
  • frontends/ui/src/features/layout/components/ChatArea.tsx
  • frontends/ui/src/features/layout/components/CitationCard.spec.tsx
  • frontends/ui/src/features/layout/components/CitationCard.tsx
  • frontends/ui/src/features/layout/components/DataConnectionCard.tsx
  • frontends/ui/src/features/layout/components/DataConnectionsTab.spec.tsx
  • frontends/ui/src/features/layout/components/DataConnectionsTab.tsx
  • frontends/ui/src/features/layout/components/DataSourcesPanel.spec.tsx
  • frontends/ui/src/features/layout/components/DataSourcesPanel.tsx
  • frontends/ui/src/features/layout/components/FileCard.tsx
  • frontends/ui/src/features/layout/components/FileSourceCard.spec.tsx
  • frontends/ui/src/features/layout/components/FileSourceCard.tsx
  • frontends/ui/src/features/layout/components/FileSourcesTab.spec.tsx
  • frontends/ui/src/features/layout/components/FileSourcesTab.tsx
  • frontends/ui/src/features/layout/components/InputArea.tsx
  • frontends/ui/src/features/layout/components/MainLayout.spec.tsx
  • frontends/ui/src/features/layout/components/MainLayout.tsx
  • frontends/ui/src/features/layout/components/ReportCard.spec.tsx
  • frontends/ui/src/features/layout/components/ReportCard.tsx
  • frontends/ui/src/features/layout/components/ReportTab.spec.tsx
  • frontends/ui/src/features/layout/components/ReportTab.tsx
  • frontends/ui/src/features/layout/components/ResearchPanel.spec.tsx
  • frontends/ui/src/features/layout/components/ResearchPanel.tsx
  • frontends/ui/src/features/layout/components/SessionsPanel.spec.tsx
  • frontends/ui/src/features/layout/components/SessionsPanel.tsx
  • frontends/ui/src/features/layout/components/SettingsPanel.spec.tsx
  • frontends/ui/src/features/layout/components/SettingsPanel.tsx
  • frontends/ui/src/features/layout/components/SourceCard.spec.tsx
  • frontends/ui/src/features/layout/components/SourceCard.tsx
  • frontends/ui/src/features/layout/components/TaskCard.spec.tsx
  • frontends/ui/src/features/layout/components/TaskCard.tsx
  • frontends/ui/src/features/layout/components/TasksTab.spec.tsx
  • frontends/ui/src/features/layout/components/TasksTab.tsx
  • frontends/ui/src/features/layout/components/ThinkingTab.spec.tsx
  • frontends/ui/src/features/layout/components/ThinkingTab.tsx
  • frontends/ui/src/features/layout/components/ThoughtCard.spec.tsx
  • frontends/ui/src/features/layout/components/ThoughtCard.tsx
  • frontends/ui/src/features/layout/components/index.ts
  • frontends/ui/src/features/layout/data-sources.spec.ts
  • frontends/ui/src/features/layout/data-sources.ts
  • frontends/ui/src/features/layout/index.ts
  • frontends/ui/src/features/layout/store.spec.ts
  • frontends/ui/src/features/layout/store.ts
  • frontends/ui/src/features/layout/types.ts
  • frontends/ui/src/shared/components/Actions/CopyButton.tsx
  • frontends/ui/src/shared/components/CollapsibleBlock/CollapsibleBlock.spec.tsx
  • frontends/ui/src/shared/components/CollapsibleBlock/CollapsibleBlock.tsx
  • frontends/ui/src/shared/components/MarkdownRenderer/Citation.tsx
  • frontends/ui/src/shared/components/MarkdownRenderer/rehype-citations.ts
  • frontends/ui/src/shared/components/Sources/SourceList.spec.tsx
  • frontends/ui/src/shared/components/Sources/SourceList.tsx
  • frontends/ui/src/shared/components/Sources/SourceStrip.tsx
  • frontends/ui/src/shared/components/Sources/source-utils.ts
  • frontends/ui/src/shared/lib/scroll.spec.ts
  • frontends/ui/src/shared/lib/scroll.ts
💤 Files with no reviewable changes (14)
  • frontends/ui/src/features/layout/components/SourceCard.spec.tsx
  • frontends/ui/src/features/chat/components/ErrorBanner.tsx
  • frontends/ui/src/features/layout/components/DataConnectionsTab.spec.tsx
  • frontends/ui/src/features/layout/components/index.ts
  • frontends/ui/src/features/layout/components/ResearchPanel.spec.tsx
  • frontends/ui/src/features/chat/components/NoSourcesBanner.tsx
  • frontends/ui/src/features/chat/components/FileUploadBanner.tsx
  • frontends/ui/src/features/layout/components/SettingsPanel.spec.tsx
  • frontends/ui/src/features/chat/components/DeepResearchBanner.tsx
  • frontends/ui/src/features/layout/components/TasksTab.spec.tsx
  • frontends/ui/src/features/layout/components/FileSourcesTab.spec.tsx
  • frontends/ui/src/features/layout/components/ReportCard.spec.tsx
  • frontends/ui/src/features/chat/components/index.ts
  • frontends/ui/src/features/layout/components/CitationCard.spec.tsx
📜 Review details
🧰 Additional context used
📓 Path-based instructions (3)
frontends/ui/**/*.{js,ts,jsx,tsx,vue}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Run npm lint, type-check, and build validation for UI changes in frontends/ui

Files:

  • frontends/ui/src/shared/lib/scroll.spec.ts
  • frontends/ui/src/shared/lib/scroll.ts
  • frontends/ui/src/shared/components/CollapsibleBlock/CollapsibleBlock.spec.tsx
  • frontends/ui/src/features/layout/components/TaskCard.spec.tsx
  • frontends/ui/src/features/layout/data-sources.spec.ts
  • frontends/ui/src/features/layout/index.ts
  • frontends/ui/src/features/layout/components/CitationCard.tsx
  • frontends/ui/src/features/layout/components/DataConnectionCard.tsx
  • frontends/ui/src/app/page.tsx
  • frontends/ui/src/features/chat/components/UserMessage.tsx
  • frontends/ui/src/features/layout/components/AgentsTab.tsx
  • frontends/ui/src/shared/components/Sources/SourceList.spec.tsx
  • frontends/ui/src/features/layout/components/SettingsPanel.tsx
  • frontends/ui/src/features/layout/components/DataSourcesPanel.spec.tsx
  • frontends/ui/src/features/layout/components/SourceCard.tsx
  • frontends/ui/src/features/layout/components/TaskCard.tsx
  • frontends/ui/src/features/layout/components/ReportTab.spec.tsx
  • frontends/ui/src/features/layout/components/AgentsTab.spec.tsx
  • frontends/ui/src/app/providers.tsx
  • frontends/ui/src/features/layout/components/ReportCard.tsx
  • frontends/ui/src/shared/components/MarkdownRenderer/rehype-citations.ts
  • frontends/ui/src/shared/components/Sources/SourceStrip.tsx
  • frontends/ui/src/features/layout/store.spec.ts
  • frontends/ui/src/shared/components/CollapsibleBlock/CollapsibleBlock.tsx
  • frontends/ui/src/features/chat/lib/deep-research-trace.ts
  • frontends/ui/src/shared/components/Sources/SourceList.tsx
  • frontends/ui/src/features/layout/components/ReportTab.tsx
  • frontends/ui/src/features/chat/lib/intermediate-step-parser.spec.ts
  • frontends/ui/src/shared/components/Actions/CopyButton.tsx
  • frontends/ui/src/features/layout/components/FileSourceCard.spec.tsx
  • frontends/ui/src/features/chat/lib/deep-research-trace.spec.ts
  • frontends/ui/src/features/layout/store.ts
  • frontends/ui/src/adapters/api/websocket-client.ts
  • frontends/ui/src/features/layout/components/ThoughtCard.spec.tsx
  • frontends/ui/src/features/layout/data-sources.ts
  • frontends/ui/src/shared/components/MarkdownRenderer/Citation.tsx
  • frontends/ui/src/features/layout/components/ChatArea.autoscroll.spec.tsx
  • frontends/ui/src/features/layout/components/InputArea.tsx
  • frontends/ui/src/features/layout/components/FileSourceCard.tsx
  • frontends/ui/src/features/chat/types.ts
  • frontends/ui/src/features/chat/store.ts
  • frontends/ui/src/features/chat/components/AgentResponse.tsx
  • frontends/ui/src/features/layout/components/ThinkingTab.tsx
  • frontends/ui/src/features/chat/lib/intermediate-step-parser.ts
  • frontends/ui/src/features/chat/store.spec.ts
  • frontends/ui/src/features/chat/components/AgentResponse.spec.tsx
  • frontends/ui/src/features/chat/components/AgentPrompt.spec.tsx
  • frontends/ui/src/features/layout/types.ts
  • frontends/ui/src/features/layout/components/ChatArea.spec.tsx
  • frontends/ui/src/features/layout/components/FileCard.tsx
  • frontends/ui/src/features/chat/components/ChatThinking.spec.tsx
  • frontends/ui/src/shared/components/Sources/source-utils.ts
  • frontends/ui/src/features/chat/lib/session-activity.ts
  • frontends/ui/src/features/layout/components/AppBar.spec.tsx
  • frontends/ui/src/features/layout/components/TasksTab.tsx
  • frontends/ui/src/features/layout/components/DataConnectionsTab.tsx
  • frontends/ui/src/features/layout/components/AppBar.tsx
  • frontends/ui/src/features/layout/components/MainLayout.tsx
  • frontends/ui/src/features/layout/components/ThoughtCard.tsx
  • frontends/ui/src/features/layout/components/MainLayout.spec.tsx
  • frontends/ui/src/features/layout/components/ResearchPanel.tsx
  • frontends/ui/src/features/layout/components/SessionsPanel.tsx
  • frontends/ui/src/features/layout/components/ThinkingTab.spec.tsx
  • frontends/ui/src/features/chat/hooks/use-websocket-chat.ts
  • frontends/ui/src/features/layout/components/AgentCard.tsx
  • frontends/ui/src/features/layout/components/AgentCard.spec.tsx
  • frontends/ui/src/features/chat/components/ChatThinking.tsx
  • frontends/ui/src/features/layout/components/DataSourcesPanel.tsx
  • frontends/ui/src/features/layout/components/FileSourcesTab.tsx
  • frontends/ui/src/features/layout/components/SessionsPanel.spec.tsx
  • frontends/ui/src/features/layout/components/ChatArea.tsx
  • frontends/ui/src/features/chat/components/AgentPrompt.tsx
frontends/ui/**/*.{ts,tsx,jsx,js}

📄 CodeRabbit inference engine (AGENTS.md)

frontends/ui/**/*.{ts,tsx,jsx,js}: The UI is built with Next.js / React / TypeScript / Tailwind with KUI components; reuse existing KUI components and visual patterns rather than introducing new ones
Validate UI-affecting changes with npm run lint, npm run type-check, and npm run test:ci, and include a screenshot for visible changes

Files:

  • frontends/ui/src/shared/lib/scroll.spec.ts
  • frontends/ui/src/shared/lib/scroll.ts
  • frontends/ui/src/shared/components/CollapsibleBlock/CollapsibleBlock.spec.tsx
  • frontends/ui/src/features/layout/components/TaskCard.spec.tsx
  • frontends/ui/src/features/layout/data-sources.spec.ts
  • frontends/ui/src/features/layout/index.ts
  • frontends/ui/src/features/layout/components/CitationCard.tsx
  • frontends/ui/src/features/layout/components/DataConnectionCard.tsx
  • frontends/ui/src/app/page.tsx
  • frontends/ui/src/features/chat/components/UserMessage.tsx
  • frontends/ui/src/features/layout/components/AgentsTab.tsx
  • frontends/ui/src/shared/components/Sources/SourceList.spec.tsx
  • frontends/ui/src/features/layout/components/SettingsPanel.tsx
  • frontends/ui/src/features/layout/components/DataSourcesPanel.spec.tsx
  • frontends/ui/src/features/layout/components/SourceCard.tsx
  • frontends/ui/src/features/layout/components/TaskCard.tsx
  • frontends/ui/src/features/layout/components/ReportTab.spec.tsx
  • frontends/ui/src/features/layout/components/AgentsTab.spec.tsx
  • frontends/ui/src/app/providers.tsx
  • frontends/ui/src/features/layout/components/ReportCard.tsx
  • frontends/ui/src/shared/components/MarkdownRenderer/rehype-citations.ts
  • frontends/ui/src/shared/components/Sources/SourceStrip.tsx
  • frontends/ui/src/features/layout/store.spec.ts
  • frontends/ui/src/shared/components/CollapsibleBlock/CollapsibleBlock.tsx
  • frontends/ui/src/features/chat/lib/deep-research-trace.ts
  • frontends/ui/src/shared/components/Sources/SourceList.tsx
  • frontends/ui/src/features/layout/components/ReportTab.tsx
  • frontends/ui/src/features/chat/lib/intermediate-step-parser.spec.ts
  • frontends/ui/src/shared/components/Actions/CopyButton.tsx
  • frontends/ui/src/features/layout/components/FileSourceCard.spec.tsx
  • frontends/ui/src/features/chat/lib/deep-research-trace.spec.ts
  • frontends/ui/src/features/layout/store.ts
  • frontends/ui/src/adapters/api/websocket-client.ts
  • frontends/ui/src/features/layout/components/ThoughtCard.spec.tsx
  • frontends/ui/src/features/layout/data-sources.ts
  • frontends/ui/src/shared/components/MarkdownRenderer/Citation.tsx
  • frontends/ui/src/features/layout/components/ChatArea.autoscroll.spec.tsx
  • frontends/ui/src/features/layout/components/InputArea.tsx
  • frontends/ui/src/features/layout/components/FileSourceCard.tsx
  • frontends/ui/src/features/chat/types.ts
  • frontends/ui/src/features/chat/store.ts
  • frontends/ui/src/features/chat/components/AgentResponse.tsx
  • frontends/ui/src/features/layout/components/ThinkingTab.tsx
  • frontends/ui/src/features/chat/lib/intermediate-step-parser.ts
  • frontends/ui/src/features/chat/store.spec.ts
  • frontends/ui/src/features/chat/components/AgentResponse.spec.tsx
  • frontends/ui/src/features/chat/components/AgentPrompt.spec.tsx
  • frontends/ui/src/features/layout/types.ts
  • frontends/ui/src/features/layout/components/ChatArea.spec.tsx
  • frontends/ui/src/features/layout/components/FileCard.tsx
  • frontends/ui/src/features/chat/components/ChatThinking.spec.tsx
  • frontends/ui/src/shared/components/Sources/source-utils.ts
  • frontends/ui/src/features/chat/lib/session-activity.ts
  • frontends/ui/src/features/layout/components/AppBar.spec.tsx
  • frontends/ui/src/features/layout/components/TasksTab.tsx
  • frontends/ui/src/features/layout/components/DataConnectionsTab.tsx
  • frontends/ui/src/features/layout/components/AppBar.tsx
  • frontends/ui/src/features/layout/components/MainLayout.tsx
  • frontends/ui/src/features/layout/components/ThoughtCard.tsx
  • frontends/ui/src/features/layout/components/MainLayout.spec.tsx
  • frontends/ui/src/features/layout/components/ResearchPanel.tsx
  • frontends/ui/src/features/layout/components/SessionsPanel.tsx
  • frontends/ui/src/features/layout/components/ThinkingTab.spec.tsx
  • frontends/ui/src/features/chat/hooks/use-websocket-chat.ts
  • frontends/ui/src/features/layout/components/AgentCard.tsx
  • frontends/ui/src/features/layout/components/AgentCard.spec.tsx
  • frontends/ui/src/features/chat/components/ChatThinking.tsx
  • frontends/ui/src/features/layout/components/DataSourcesPanel.tsx
  • frontends/ui/src/features/layout/components/FileSourcesTab.tsx
  • frontends/ui/src/features/layout/components/SessionsPanel.spec.tsx
  • frontends/ui/src/features/layout/components/ChatArea.tsx
  • frontends/ui/src/features/chat/components/AgentPrompt.tsx
frontends/ui/**/*

⚙️ CodeRabbit configuration file

frontends/ui/**/*: Review UI changes for strict TypeScript behavior, API contract alignment, auth/session handling, accessible controls,
resilient loading and error states, and report/chat state consistency. Prefer existing UI patterns and require tests
for changed user-visible workflows.

Files:

  • frontends/ui/src/shared/lib/scroll.spec.ts
  • frontends/ui/src/shared/lib/scroll.ts
  • frontends/ui/src/shared/components/CollapsibleBlock/CollapsibleBlock.spec.tsx
  • frontends/ui/src/features/layout/components/TaskCard.spec.tsx
  • frontends/ui/src/features/layout/data-sources.spec.ts
  • frontends/ui/src/features/layout/index.ts
  • frontends/ui/src/features/layout/components/CitationCard.tsx
  • frontends/ui/src/features/layout/components/DataConnectionCard.tsx
  • frontends/ui/src/app/page.tsx
  • frontends/ui/src/features/chat/components/UserMessage.tsx
  • frontends/ui/src/features/layout/components/AgentsTab.tsx
  • frontends/ui/src/shared/components/Sources/SourceList.spec.tsx
  • frontends/ui/src/features/layout/components/SettingsPanel.tsx
  • frontends/ui/src/features/layout/components/DataSourcesPanel.spec.tsx
  • frontends/ui/src/features/layout/components/SourceCard.tsx
  • frontends/ui/src/features/layout/components/TaskCard.tsx
  • frontends/ui/src/features/layout/components/ReportTab.spec.tsx
  • frontends/ui/src/features/layout/components/AgentsTab.spec.tsx
  • frontends/ui/src/app/providers.tsx
  • frontends/ui/src/features/layout/components/ReportCard.tsx
  • frontends/ui/src/shared/components/MarkdownRenderer/rehype-citations.ts
  • frontends/ui/src/shared/components/Sources/SourceStrip.tsx
  • frontends/ui/src/features/layout/store.spec.ts
  • frontends/ui/src/shared/components/CollapsibleBlock/CollapsibleBlock.tsx
  • frontends/ui/src/features/chat/lib/deep-research-trace.ts
  • frontends/ui/src/shared/components/Sources/SourceList.tsx
  • frontends/ui/src/features/layout/components/ReportTab.tsx
  • frontends/ui/src/features/chat/lib/intermediate-step-parser.spec.ts
  • frontends/ui/src/shared/components/Actions/CopyButton.tsx
  • frontends/ui/src/features/layout/components/FileSourceCard.spec.tsx
  • frontends/ui/src/features/chat/lib/deep-research-trace.spec.ts
  • frontends/ui/src/features/layout/store.ts
  • frontends/ui/src/adapters/api/websocket-client.ts
  • frontends/ui/src/features/layout/components/ThoughtCard.spec.tsx
  • frontends/ui/src/features/layout/data-sources.ts
  • frontends/ui/src/shared/components/MarkdownRenderer/Citation.tsx
  • frontends/ui/src/features/layout/components/ChatArea.autoscroll.spec.tsx
  • frontends/ui/src/features/layout/components/InputArea.tsx
  • frontends/ui/src/features/layout/components/FileSourceCard.tsx
  • frontends/ui/src/features/chat/types.ts
  • frontends/ui/src/features/chat/store.ts
  • frontends/ui/src/features/chat/components/AgentResponse.tsx
  • frontends/ui/src/features/layout/components/ThinkingTab.tsx
  • frontends/ui/src/features/chat/lib/intermediate-step-parser.ts
  • frontends/ui/src/features/chat/store.spec.ts
  • frontends/ui/src/features/chat/components/AgentResponse.spec.tsx
  • frontends/ui/src/features/chat/components/AgentPrompt.spec.tsx
  • frontends/ui/src/features/layout/types.ts
  • frontends/ui/src/features/layout/components/ChatArea.spec.tsx
  • frontends/ui/src/features/layout/components/FileCard.tsx
  • frontends/ui/src/features/chat/components/ChatThinking.spec.tsx
  • frontends/ui/src/shared/components/Sources/source-utils.ts
  • frontends/ui/src/features/chat/lib/session-activity.ts
  • frontends/ui/src/features/layout/components/AppBar.spec.tsx
  • frontends/ui/src/features/layout/components/TasksTab.tsx
  • frontends/ui/src/features/layout/components/DataConnectionsTab.tsx
  • frontends/ui/src/features/layout/components/AppBar.tsx
  • frontends/ui/src/features/layout/components/MainLayout.tsx
  • frontends/ui/src/features/layout/components/ThoughtCard.tsx
  • frontends/ui/src/features/layout/components/MainLayout.spec.tsx
  • frontends/ui/src/features/layout/components/ResearchPanel.tsx
  • frontends/ui/src/features/layout/components/SessionsPanel.tsx
  • frontends/ui/src/features/layout/components/ThinkingTab.spec.tsx
  • frontends/ui/src/features/chat/hooks/use-websocket-chat.ts
  • frontends/ui/src/features/layout/components/AgentCard.tsx
  • frontends/ui/src/features/layout/components/AgentCard.spec.tsx
  • frontends/ui/src/features/chat/components/ChatThinking.tsx
  • frontends/ui/src/features/layout/components/DataSourcesPanel.tsx
  • frontends/ui/src/features/layout/components/FileSourcesTab.tsx
  • frontends/ui/src/features/layout/components/SessionsPanel.spec.tsx
  • frontends/ui/src/features/layout/components/ChatArea.tsx
  • frontends/ui/src/features/chat/components/AgentPrompt.tsx
  • frontends/ui/src/app/globals.css
🪛 Stylelint (17.14.0)
frontends/ui/src/app/globals.css

[error] 670-670: Deprecated keyword "break-word" for property "word-break" (declaration-property-value-keyword-no-deprecated)

(declaration-property-value-keyword-no-deprecated)


[error] 453-453: Expected keyframe name "assistantTurnIn" to be kebab-case (keyframes-name-pattern)

(keyframes-name-pattern)


[error] 522-522: Expected keyframe name "thinkingDot" to be kebab-case (keyframes-name-pattern)

(keyframes-name-pattern)


[error] 596-596: Expected keyframe name "thinkSweep" to be kebab-case (keyframes-name-pattern)

(keyframes-name-pattern)


[error] 745-745: Expected keyframe name "answerBlockReveal" to be kebab-case (keyframes-name-pattern)

(keyframes-name-pattern)

Comment thread frontends/ui/src/app/globals.css
Comment thread frontends/ui/src/features/chat/components/AgentPrompt.spec.tsx
Comment thread frontends/ui/src/features/chat/components/AgentResponse.spec.tsx Outdated
Comment thread frontends/ui/src/features/chat/components/ChatThinking.tsx Outdated
Comment thread frontends/ui/src/features/chat/components/ChatThinking.tsx
Comment thread frontends/ui/src/features/layout/components/AgentsTab.tsx
Comment thread frontends/ui/src/features/layout/components/AgentsTab.tsx Outdated
Comment thread frontends/ui/src/features/layout/components/ChatArea.tsx
Comment thread frontends/ui/src/features/layout/components/SessionsPanel.tsx
Comment thread frontends/ui/src/features/layout/components/ThinkingTab.tsx
@AjayThorve

Copy link
Copy Markdown
Collaborator

/ok to test 69fc3d1

@AjayThorve
AjayThorve changed the base branch from develop to release/2.2 July 14, 2026 21:53
@AjayThorve
AjayThorve changed the base branch from release/2.2 to develop July 14, 2026 21:53

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
frontends/ui/src/features/chat/components/ChatThinking.tsx (3)

583-603: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Keep reasoning-only phases renderable.

realSteps removes reasoning/explanation entries, while buildPhases(visibleSteps) retains them in phase metadata and supports fallback phases. A reasoning-only stream can therefore have renderable phases but still hit the return null guard at Line [602], hiding the live trace before any tool phase appears.

Gate on phases.length (or another renderable-phase predicate) and add a reasoning-only regression test.

Proposed fix
-  if (realSteps.length === 0 && !hasDataSources && !hasFiles) {
+  if (phases.length === 0 && !hasDataSources && !hasFiles) {
     return null
   }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontends/ui/src/features/chat/components/ChatThinking.tsx` around lines 583
- 603, Update the render guard in ChatThinking so reasoning-only streams remain
renderable: use the built phases collection (such as phases.length) rather than
realSteps.length when deciding to return null, while preserving the existing
data-source and file checks. Add a regression test covering a reasoning-only
visibleSteps stream and verifying its phase metadata is rendered.

697-704: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Associate the disclosure with the trace region.
aria-expanded needs a matching aria-controls target, and the trace panel should have a stable id. When phases.length === 0, render a static header instead of a button so it doesn’t imply a panel that isn’t there.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontends/ui/src/features/chat/components/ChatThinking.tsx` around lines 697
- 704, Update the ChatThinking disclosure so the button’s aria-expanded is
paired with aria-controls referencing a stable id on the trace panel. When
phases.length is zero, render a non-interactive static header instead of the
disclosure button; preserve the existing toggle behavior and trace content for
non-empty phases.

Source: Path instructions


552-555: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Update responseNow when thinking stops. When responseCompletedAt is absent, the timer can freeze on the last 1s tick, so responseDuration may render up to a second short after thinking ends. Set responseNow to Date.now() alongside stoppedAt in frontends/ui/src/features/chat/components/ChatThinking.tsx:552-555.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontends/ui/src/features/chat/components/ChatThinking.tsx` around lines 552
- 555, Update the thinking-stop branch guarded by wasThinkingRef.current to also
set responseNow to Date.now() alongside stoppedAt, ensuring the final
responseDuration calculation uses the stop timestamp when responseCompletedAt is
absent.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@frontends/ui/src/features/chat/components/ChatThinking.tsx`:
- Around line 583-603: Update the render guard in ChatThinking so reasoning-only
streams remain renderable: use the built phases collection (such as
phases.length) rather than realSteps.length when deciding to return null, while
preserving the existing data-source and file checks. Add a regression test
covering a reasoning-only visibleSteps stream and verifying its phase metadata
is rendered.
- Around line 697-704: Update the ChatThinking disclosure so the button’s
aria-expanded is paired with aria-controls referencing a stable id on the trace
panel. When phases.length is zero, render a non-interactive static header
instead of the disclosure button; preserve the existing toggle behavior and
trace content for non-empty phases.
- Around line 552-555: Update the thinking-stop branch guarded by
wasThinkingRef.current to also set responseNow to Date.now() alongside
stoppedAt, ensuring the final responseDuration calculation uses the stop
timestamp when responseCompletedAt is absent.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Enterprise

Run ID: fb0315fa-5198-485c-aa3d-7cb5cfe5a460

📥 Commits

Reviewing files that changed from the base of the PR and between 138aa63 and ba52d13.

📒 Files selected for processing (2)
  • frontends/ui/src/app/globals.css
  • frontends/ui/src/features/chat/components/ChatThinking.tsx
📜 Review details
🧰 Additional context used
📓 Path-based instructions (3)
frontends/ui/**/*.{js,ts,jsx,tsx,vue}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Run npm lint, type-check, and build validation for UI changes in frontends/ui

Files:

  • frontends/ui/src/features/chat/components/ChatThinking.tsx
frontends/ui/**/*.{ts,tsx,jsx,js}

📄 CodeRabbit inference engine (AGENTS.md)

frontends/ui/**/*.{ts,tsx,jsx,js}: The UI is built with Next.js / React / TypeScript / Tailwind with KUI components; reuse existing KUI components and visual patterns rather than introducing new ones
Validate UI-affecting changes with npm run lint, npm run type-check, and npm run test:ci, and include a screenshot for visible changes

Files:

  • frontends/ui/src/features/chat/components/ChatThinking.tsx
frontends/ui/**/*

⚙️ CodeRabbit configuration file

frontends/ui/**/*: Review UI changes for strict TypeScript behavior, API contract alignment, auth/session handling, accessible controls,
resilient loading and error states, and report/chat state consistency. Prefer existing UI patterns and require tests
for changed user-visible workflows.

Files:

  • frontends/ui/src/features/chat/components/ChatThinking.tsx
  • frontends/ui/src/app/globals.css
🪛 Stylelint (17.14.0)
frontends/ui/src/app/globals.css

[error] 130-130: Expected "optimizeLegibility" to be "optimizelegibility" (value-keyword-case)

(value-keyword-case)

🔇 Additional comments (2)
frontends/ui/src/app/globals.css (1)

127-130: 📐 Maintainability & Code Quality

No change needed. text-rendering: optimizeLegibility is valid CSS, and this frontend config doesn’t include a Stylelint rule that requires a lowercase keyword form.

			> Likely an incorrect or invalid review comment.
frontends/ui/src/features/chat/components/ChatThinking.tsx (1)

641-643: 🎯 Functional Correctness

No issue here: phases only contains observed steps. buildPhases() creates each phase from an actual ThinkingStep, and the trace contract says top-level steps are emitted in start order. laterStarted is just using the next observed phase as the completion boundary for earlier phases.

			> Likely an incorrect or invalid review comment.

@KyleZheng1284 KyleZheng1284 added enhancement New feature or request UI/UX UI and UX related fixes READY FOR REVIEW labels Jul 15, 2026
@KyleZheng1284
KyleZheng1284 self-requested a review July 15, 2026 23:24
Manushpm8 and others added 4 commits July 16, 2026 08:13
Signed-off-by: Manush Maheshwari <manushm@nvidia.com>
Additive state and streaming plumbing that a later UI PR consumes; no visual
change and no prod capability removed.

- chat types: optional ThinkingStep fields (completedAt, status, argSummary),
  ChatMessage.selectedModel, and a plan_approval prompt type.
- intermediate-step-parser: generic folded reasoning/reflection/explanation
  sentinels and predicates, splitPayload/extractFoldedOutput, and label lookup
  via the shared tool-label engine.
- deep-research-trace: replays a stored deep run into the same ThinkingStep
  stream so reloaded reports show an identical trace.
- store + use-websocket-chat: populate the new step fields as the run streams,
  fail steps on error, and thread the selected model through send.
- layout store: a sidebar collapse model added alongside the existing panel
  API, a prompt draft, a selected-model slot, and data-source display helpers.

Per-user auth, WebSocket token rotation, artifact handling, and HITL are
preserved unchanged. No predictive/analytical/warehouse plumbing is ported.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Manush Maheshwari <manushm@nvidia.com>
- deep-research-trace: preserve tool calls whose referenced agent is missing
  (dangling agentId), not just calls with no agent, and add a regression test.
- store: scope deep-research hydration to the current user's conversations.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Manush Maheshwari <manushm@nvidia.com>
Signed-off-by: Manush Maheshwari <manushm@nvidia.com>
@Manushpm8
Manushpm8 force-pushed the feat/ui-chat-look branch from ba52d13 to 6d43fc5 Compare July 16, 2026 03:50
@Manushpm8
Manushpm8 requested a review from a team July 16, 2026 03:50

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 33

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
frontends/ui/src/features/layout/components/ThinkingTab.spec.tsx (1)

86-120: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Cover the zero-match Cited filter state.

Add a case containing only uncited sources, select Cited (0), and assert the filter-specific empty message rather than the global Sources empty state.

As per path instructions, require tests for changed user-visible workflows.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontends/ui/src/features/layout/components/ThinkingTab.spec.tsx` around
lines 86 - 120, Add a test alongside the existing source-filter test that
configures only uncited entries in mockState, renders ThinkingTab, selects the
“Cited (0)” radio control, and asserts the filter-specific empty-state message
is shown while the global Sources empty message is not.

Source: Path instructions

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/source/customization/configuration-reference.md`:
- Line 605: Update the configuration-profile count in the introduction of
configuration-reference.md from nine to ten, matching the ten profiles listed in
the table, including configs/config_web_azure_ai_search.yml. Review nearby
documentation for stale examples of the old count and update only those
references.

In `@docs/source/customization/knowledge-layer.md`:
- Around line 488-489: Update the environment-variable table in the
knowledge-layer customization documentation to include AZURE_SEARCH_ENDPOINT,
AZURE_SEARCH_API_KEY, AIQ_AZURE_SEARCH_INDEX_PREFIX, and AIQ_EMBED_DIM. Extend
the existing AIQ_EMBED_MODEL/AIQ_EMBED_BASE_URL entry to cover Azure AI Search,
keeping the table consistent with the Azure configuration documented in the
earlier section and correcting any stale or inaccurate examples encountered
there.

In `@docs/source/deployment/openshell.md`:
- Around line 203-211: Update the canonical openshell gateway command in the
deployment documentation to include --reuse-existing for external gateways.
Clearly label any command that omits this flag as the local packaged-service
variant where the launcher may start systemd, and keep the documented lifecycle
behavior consistent with the surrounding guidance.

In `@frontends/ui/src/app/globals.css`:
- Line 88: Update the light and dark theme values for --text-color-subtle to
achieve at least 4.5:1 contrast against their respective base and raised
surfaces, then validate both theme combinations. Add or update tests covering
the affected user-visible UI workflows and accessible controls.
- Line 130: Update the text-rendering declaration to use Stylelint’s canonical
casing for the optimizeLegibility keyword, while preserving the existing
property and value.

In `@frontends/ui/src/features/chat/components/AgentPrompt.tsx`:
- Around line 200-237: The global keydown handler in the AgentPrompt useEffect
must not intercept activation of focused interactive controls, especially the
Reject button. Extend isTyping or otherwise detect focused buttons and other
interactive targets before handling shortcuts, preserving native
Enter/activation behavior; add a regression test that focuses Reject and
activates it with Enter, verifying rejection occurs instead of handleApprove.
- Around line 143-154: Update AgentPrompt to use the destructured prompt type as
the primary approval determination, treating type="approval" as an approval
prompt regardless of content; retain the APPROVAL_PROMPT_RE check only as a
compatibility fallback if required. Add coverage for an approval-typed prompt
whose content lacks the legacy phrase, verifying the approval controls are
rendered.

In `@frontends/ui/src/features/chat/components/ChatThinking.tsx`:
- Around line 333-337: Update childState and its callers to accept the parent
phase state, propagating error or interrupted terminal outcomes to children that
are not complete instead of marking them done. Preserve child-level
error/success handling and running-phase behavior for active phases. Add focused
tests covering incomplete children under errored and interrupted phases while
preserving report/chat state consistency.
- Around line 66-71: Update formatDuration to round the non-negative duration to
whole seconds before calculating minutes and remaining seconds, then derive both
values using quotient and modulo arithmetic so carry-over values such as
119600ms render as 2m 0s while sub-minute durations retain the existing
one-decimal format.
- Around line 179-198: Replace the label-only filtering and argument merging in
the topLevelLabels/nestedSummaries/enriched flow, since same-label calls may
have different inputs and non-tool rows must not be removed. Preserve ambiguous
rows and defer deduplication to the existing exact label/input grouping logic
below, while retaining identifiable-call deduplication. Add focused regression
tests for same-label calls with different arguments and same-label non-tool
rows, ensuring report and chat state remain consistent.

In `@frontends/ui/src/features/chat/lib/deep-research-trace.ts`:
- Around line 35-56: Update the trace deduplication logic in the step-processing
flow, including sameCall, sameFold, and lastToolIndex, to use each tool or fold
step’s event ID as identity rather than function, arguments, or content. Replace
an existing snapshot when the ID matches, while preserving distinct steps with
identical inputs and ensuring newer snapshots replace stale explanation content.
Add regression coverage for distinct IDs with identical inputs and updated
snapshots sharing one ID.

In `@frontends/ui/src/features/layout/components/AgentCard.spec.tsx`:
- Around line 219-225: Extend the disabled/no-content AgentCard test to verify
its accessible button state: assert aria-expanded is "false" and aria-controls
is absent when no content region is rendered. Keep the existing expandable-case
assertions unchanged.

In `@frontends/ui/src/features/layout/components/AgentCard.tsx`:
- Around line 102-108: Update the AgentCard button’s accessibility attributes so
aria-expanded is false and aria-controls is omitted whenever canExpand is false,
while preserving the existing expanded state and controlled-region reference for
expandable cards. Add assertions in
frontends/ui/src/features/layout/components/AgentCard.spec.tsx:219-225 for the
no-content case;
frontends/ui/src/features/layout/components/AgentCard.tsx:102-108 requires the
implementation change.

In `@frontends/ui/src/features/layout/components/AppBar.spec.tsx`:
- Around line 105-122: Add tests in the AppBar interaction suite covering the
already-open data-sources state and the dark-theme state. Configure the relevant
mocked state before rendering AppBar, click the existing Add Sources and
theme-toggle buttons, and assert mockCloseRightPanel and mockSetTheme are called
with 'light' respectively, while preserving the existing opposite-direction
cases.

In `@frontends/ui/src/features/layout/components/DataSourcesPanel.tsx`:
- Around line 316-365: Remove the row’s interactive button semantics and
handlers from the Flex container, including role, tabIndex, click, keyboard, and
button-specific ARIA attributes. Keep the KUI Switch as the sole interactive
control, preserving its checked state, disabled behavior, accessible label, and
handleToggleAll callback; retain suitable visual styling without relying on
interactive-row behavior.
- Around line 388-395: Update the Retry button’s onClick handler in
DataSourcesPanel to call fetchDataSources with the current idToken, matching the
existing authenticated refresh path and preserving the API contract. Add or
update the relevant test to verify the token is forwarded on retry.
- Around line 220-245: Update the DataSourcesPanel close flow to move focus back
to the AppBar “Add data sources” trigger before or when the panel becomes
aria-hidden, rather than leaving focus inside the panel. Reuse the trigger’s
existing ref or accessible identifier, and add a regression test that opens the
panel, closes it, and verifies focus returns to that trigger.

In `@frontends/ui/src/features/layout/components/MainLayout.spec.tsx`:
- Around line 121-125: Update the unauthenticated MainLayout test to also assert
that the element identified by data-sources-panel is absent, matching the
existing sessions-panel assertion and the test’s stated coverage.

In `@frontends/ui/src/features/layout/components/SessionsPanel.tsx`:
- Around line 303-317: Restore a visible keyboard focus indicator on both inputs
in SessionsPanel.tsx: add the existing KUI input focus treatment or an
equivalent focus-visible ring to the search input at lines 303-317 and the
rename input at lines 612-622, replacing the ineffective outline-none-only
styling while preserving their current behavior.
- Around line 418-424: Apply the same streaming and pending-HITL navigation
guard used by the top “New Session” action to the empty-state button’s
handleNewSession path in SessionsPanel. Preserve the existing search visibility
condition, and add regression coverage verifying the empty-state button cannot
navigate during streaming or pending HITL.

In `@frontends/ui/src/features/layout/components/ThinkingTab.tsx`:
- Around line 97-106: Update the empty-state branch in ThinkingTab so a
non-empty source collection with no cited items displays “No cited sources yet,”
while the existing research-empty message remains for genuinely source-free
states; add a regression test in ThinkingTab.spec.tsx covering only uncited
sources and selecting Cited (0).

In `@scripts/openshell/check_versions.py`:
- Line 24: Update _VERSION_PATTERN used by _extract_version() to require a valid
suffix boundary after the supported version formats, preventing matches within
rc, post, or local-version strings. Add tests covering 0.0.80rc1, 0.0.80.post1,
and 0.0.80+local, while preserving matches for the existing supported
development and git-suffix forms.

In `@scripts/openshell/setup_openshell.sh`:
- Line 83: Update the help text in setup_openshell.sh to derive the example
version from the certified version value loaded from pyproject.toml instead of
hardcoding 0.0.80. Apply the same change to both the option description and the
corresponding usage example, preserving the existing certified-version contract.
- Around line 148-151: Update the --landlock-compatibility handling in the
option-parsing logic to validate that a value argument exists before reading $2,
including under set -u; when missing, emit the intended CLI error and exit
through the existing validation path, otherwise preserve the current assignment
and shift behavior.

In `@scripts/openshell/smoke_openshell_isolation.py`:
- Around line 71-73: Update the environment construction logic around the
allow_best_effort_landlock flag so AIQ_OPENSHELL_LIVE_ALLOW_BEST_EFFORT is
removed from env when the flag is absent, and set to "1" only when the flag is
enabled. Preserve the existing return env behavior.

In `@scripts/openshell/version_contract.py`:
- Around line 24-27: Update OpenShellContract.adapter_version to the required
str type, matching load_contract()’s validation and string return contract; do
not add optional handling unless the loader and extra-version comparison are
explicitly changed to support None.

In `@sources/knowledge_layer/src/azure_ai_search/adapter.py`:
- Around line 761-762: Validate job_config metadata in submit_job before
json.dumps() and before any {**file_metadata, ...} expansion, requiring a
dict/mapping and rejecting other values explicitly. Preserve the existing
empty-metadata default, and ensure invalid metadata follows the failed-job
recording path instead of raising during submission.
- Around line 1231-1249: Update upload_file around submit_job and the subsequent
_jobs[job_id].file_details access to handle a job with no file details when the
file disappears between validation checks. Return a failed FileInfo with the
file path, collection, and clear error message when file_details is empty, while
preserving the existing detail-copy path when a detail is available.
- Around line 1127-1131: Update _update_file_progress so it revalidates the
collection’s active state immediately before calling _write_file_manifest,
preventing a concurrent delete_collection from allowing the manifest write.
Preserve summary registration only when the manifest write remains valid, and
use the existing collection status/deletion state symbols.
- Around line 1258-1283: Update delete_file and delete_collection in
sources/knowledge_layer/src/azure_ai_search/adapter.py at lines 1258-1283 and
1182-1201 so they wait for all deleted Azure Search records to disappear before
returning. In delete_file, extend the post-delete _wait_for_search_state check
beyond the file manifest to include its chunk records; in delete_collection, add
an equivalent absence wait for the collection’s content after issuing deletions.

In `@src/aiq_agent/agents/deep_researcher/register.py`:
- Around line 298-306: The synchronous provider cleanup in the deep-researcher
finalization path and the API job terminal cleanup remain unbounded. Add
provider-level deadlines and call-site timeouts around the
`active_agent.finalize` flow in `register.py` and the corresponding terminal
cleanup in `runner.py`; preserve agent async cancellation semantics and the API
async job lifecycle while ensuring both request/task completions cannot wait
indefinitely.

In `@tests/aiq_agent/jobs/test_runner.py`:
- Around line 1189-1200: Update _get_worker_function_type to safely treat a
missing workflow.use_async_deep_research attribute as False, while preserving
the existing enabled and disabled behavior. Restore coverage using a workflow
configuration without the async flag and add the required job state transition
tests for the job-runner change.
- Around line 888-891: Update the job-runner failure handling that calls
mock_job_store.update_status with JobStatus.FAILURE so externally persisted
errors use a stable sanitized message instead of str(error). Keep detailed
exception information restricted to secret-safe server logging, and adjust the
expectation around update_status accordingly.

---

Outside diff comments:
In `@frontends/ui/src/features/layout/components/ThinkingTab.spec.tsx`:
- Around line 86-120: Add a test alongside the existing source-filter test that
configures only uncited entries in mockState, renders ThinkingTab, selects the
“Cited (0)” radio control, and asserts the filter-specific empty-state message
is shown while the global Sources empty message is not.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Enterprise

Run ID: 85c6fd14-a7d1-4cfa-9696-5212b4bc4f6d

📥 Commits

Reviewing files that changed from the base of the PR and between ba52d13 and 6d43fc5.

⛔ Files ignored due to path filters (1)
  • uv.lock is excluded by !**/*.lock
📒 Files selected for processing (154)
  • .secrets.baseline
  • configs/config_openshell.yml
  • configs/config_web_azure_ai_search.yml
  • configs/openshell/README.md
  • configs/openshell/aiq-research-policy.yaml
  • deploy/.env.example
  • deploy/openshell/Dockerfile.aiq-demo
  • docs/source/architecture/agents/sandbox.md
  • docs/source/customization/configuration-reference.md
  • docs/source/customization/knowledge-layer.md
  • docs/source/deployment/index.md
  • docs/source/deployment/openshell.md
  • docs/source/deployment/production.md
  • docs/source/examples/azure-ai-search.md
  • docs/source/examples/index.md
  • docs/source/index.md
  • docs/source/integration/rest-api.md
  • docs/source/resources/troubleshooting.md
  • frontends/aiq_api/src/aiq_api/jobs/runner.py
  • frontends/ui/src/adapters/api/websocket-client.ts
  • frontends/ui/src/app/globals.css
  • frontends/ui/src/app/page.tsx
  • frontends/ui/src/app/providers.tsx
  • frontends/ui/src/features/chat/components/AgentPrompt.spec.tsx
  • frontends/ui/src/features/chat/components/AgentPrompt.tsx
  • frontends/ui/src/features/chat/components/AgentResponse.spec.tsx
  • frontends/ui/src/features/chat/components/AgentResponse.tsx
  • frontends/ui/src/features/chat/components/ChatThinking.spec.tsx
  • frontends/ui/src/features/chat/components/ChatThinking.tsx
  • frontends/ui/src/features/chat/components/DeepResearchBanner.tsx
  • frontends/ui/src/features/chat/components/ErrorBanner.tsx
  • frontends/ui/src/features/chat/components/FileUploadBanner.tsx
  • frontends/ui/src/features/chat/components/NoSourcesBanner.tsx
  • frontends/ui/src/features/chat/components/UserMessage.tsx
  • frontends/ui/src/features/chat/components/index.ts
  • frontends/ui/src/features/chat/hooks/use-websocket-chat.ts
  • frontends/ui/src/features/chat/lib/deep-research-trace.spec.ts
  • frontends/ui/src/features/chat/lib/deep-research-trace.ts
  • frontends/ui/src/features/chat/lib/intermediate-step-parser.spec.ts
  • frontends/ui/src/features/chat/lib/intermediate-step-parser.ts
  • frontends/ui/src/features/chat/lib/session-activity.ts
  • frontends/ui/src/features/chat/store.spec.ts
  • frontends/ui/src/features/chat/store.ts
  • frontends/ui/src/features/chat/types.ts
  • frontends/ui/src/features/layout/components/AgentCard.spec.tsx
  • frontends/ui/src/features/layout/components/AgentCard.tsx
  • frontends/ui/src/features/layout/components/AgentsTab.spec.tsx
  • frontends/ui/src/features/layout/components/AgentsTab.tsx
  • frontends/ui/src/features/layout/components/AppBar.spec.tsx
  • frontends/ui/src/features/layout/components/AppBar.tsx
  • frontends/ui/src/features/layout/components/ChatArea.autoscroll.spec.tsx
  • frontends/ui/src/features/layout/components/ChatArea.spec.tsx
  • frontends/ui/src/features/layout/components/ChatArea.tsx
  • frontends/ui/src/features/layout/components/CitationCard.spec.tsx
  • frontends/ui/src/features/layout/components/CitationCard.tsx
  • frontends/ui/src/features/layout/components/DataConnectionCard.tsx
  • frontends/ui/src/features/layout/components/DataConnectionsTab.spec.tsx
  • frontends/ui/src/features/layout/components/DataConnectionsTab.tsx
  • frontends/ui/src/features/layout/components/DataSourcesPanel.spec.tsx
  • frontends/ui/src/features/layout/components/DataSourcesPanel.tsx
  • frontends/ui/src/features/layout/components/FileCard.tsx
  • frontends/ui/src/features/layout/components/FileSourceCard.spec.tsx
  • frontends/ui/src/features/layout/components/FileSourceCard.tsx
  • frontends/ui/src/features/layout/components/FileSourcesTab.spec.tsx
  • frontends/ui/src/features/layout/components/FileSourcesTab.tsx
  • frontends/ui/src/features/layout/components/InputArea.tsx
  • frontends/ui/src/features/layout/components/MainLayout.spec.tsx
  • frontends/ui/src/features/layout/components/MainLayout.tsx
  • frontends/ui/src/features/layout/components/ReportCard.spec.tsx
  • frontends/ui/src/features/layout/components/ReportCard.tsx
  • frontends/ui/src/features/layout/components/ReportTab.spec.tsx
  • frontends/ui/src/features/layout/components/ReportTab.tsx
  • frontends/ui/src/features/layout/components/ResearchPanel.spec.tsx
  • frontends/ui/src/features/layout/components/ResearchPanel.tsx
  • frontends/ui/src/features/layout/components/SessionsPanel.spec.tsx
  • frontends/ui/src/features/layout/components/SessionsPanel.tsx
  • frontends/ui/src/features/layout/components/SettingsPanel.spec.tsx
  • frontends/ui/src/features/layout/components/SettingsPanel.tsx
  • frontends/ui/src/features/layout/components/SourceCard.spec.tsx
  • frontends/ui/src/features/layout/components/SourceCard.tsx
  • frontends/ui/src/features/layout/components/TaskCard.spec.tsx
  • frontends/ui/src/features/layout/components/TaskCard.tsx
  • frontends/ui/src/features/layout/components/TasksTab.spec.tsx
  • frontends/ui/src/features/layout/components/TasksTab.tsx
  • frontends/ui/src/features/layout/components/ThinkingTab.spec.tsx
  • frontends/ui/src/features/layout/components/ThinkingTab.tsx
  • frontends/ui/src/features/layout/components/ThoughtCard.spec.tsx
  • frontends/ui/src/features/layout/components/ThoughtCard.tsx
  • frontends/ui/src/features/layout/components/index.ts
  • frontends/ui/src/features/layout/data-sources.spec.ts
  • frontends/ui/src/features/layout/data-sources.ts
  • frontends/ui/src/features/layout/index.ts
  • frontends/ui/src/features/layout/store.spec.ts
  • frontends/ui/src/features/layout/store.ts
  • frontends/ui/src/features/layout/types.ts
  • frontends/ui/src/shared/components/CollapsibleBlock/CollapsibleBlock.tsx
  • frontends/ui/src/shared/components/Mermaid/MermaidBlock.spec.tsx
  • frontends/ui/src/shared/components/Mermaid/MermaidBlock.tsx
  • frontends/ui/src/shared/components/Sources/SourceStrip.spec.tsx
  • frontends/ui/src/shared/components/Sources/SourceStrip.tsx
  • frontends/ui/src/shared/components/Sources/parse-references.spec.ts
  • frontends/ui/src/shared/lib/motion.spec.tsx
  • frontends/ui/src/shared/lib/scroll.spec.ts
  • frontends/ui/src/shared/lib/scroll.ts
  • pyproject.toml
  • scripts/README.md
  • scripts/openshell/check_openshell_readiness.py
  • scripts/openshell/check_versions.py
  • scripts/openshell/install_gateway.sh
  • scripts/openshell/setup_openshell.sh
  • scripts/openshell/smoke_openshell_isolation.py
  • scripts/openshell/start_openshell_gateway.sh
  • scripts/openshell/version_contract.py
  • scripts/start_e2e.sh
  • sources/knowledge_layer/KNOWLEDGE-LAYER-SETUP.md
  • sources/knowledge_layer/README.md
  • sources/knowledge_layer/pyproject.toml
  • sources/knowledge_layer/src/__init__.py
  • sources/knowledge_layer/src/azure_ai_search/README.md
  • sources/knowledge_layer/src/azure_ai_search/__init__.py
  • sources/knowledge_layer/src/azure_ai_search/adapter.py
  • sources/knowledge_layer/src/register.py
  • src/aiq_agent/agents/deep_researcher/agent.py
  • src/aiq_agent/agents/deep_researcher/custom_middleware.py
  • src/aiq_agent/agents/deep_researcher/deepagents_runtime.py
  • src/aiq_agent/agents/deep_researcher/factory.py
  • src/aiq_agent/agents/deep_researcher/prompts/writer.j2
  • src/aiq_agent/agents/deep_researcher/register.py
  • src/aiq_agent/agents/deep_researcher/sandbox/README.md
  • src/aiq_agent/agents/deep_researcher/sandbox/artifacts/manager.py
  • src/aiq_agent/agents/deep_researcher/sandbox/artifacts/store.py
  • src/aiq_agent/agents/deep_researcher/sandbox/base.py
  • src/aiq_agent/agents/deep_researcher/sandbox/config.py
  • src/aiq_agent/agents/deep_researcher/sandbox/logging_utils.py
  • src/aiq_agent/agents/deep_researcher/sandbox/providers/openshell.py
  • src/aiq_agent/agents/deep_researcher/sandbox/registry.py
  • src/aiq_agent/agents/deep_researcher/skills/research/chart-generation/SKILL.md
  • tests/aiq_agent/agents/deep_researcher/sandbox/test_artifacts.py
  • tests/aiq_agent/agents/deep_researcher/sandbox/test_openshell_live.py
  • tests/aiq_agent/agents/deep_researcher/sandbox/test_openshell_provider.py
  • tests/aiq_agent/agents/deep_researcher/sandbox/test_sandbox_runtime.py
  • tests/aiq_agent/agents/deep_researcher/test_agent.py
  • tests/aiq_agent/agents/deep_researcher/test_chart_artifact_contract.py
  • tests/aiq_agent/agents/deep_researcher/test_custom_middleware.py
  • tests/aiq_agent/agents/deep_researcher/test_deepagents_runtime.py
  • tests/aiq_agent/agents/deep_researcher/test_factory.py
  • tests/aiq_agent/jobs/test_runner.py
  • tests/knowledge_layer_tests/run_adapter_compliance.py
  • tests/knowledge_layer_tests/test_azure_ai_search.py
  • tests/scripts/test_openshell_gateway_installer.py
  • tests/scripts/test_openshell_lifecycle_scripts.py
  • tests/scripts/test_openshell_readiness_checker.py
  • tests/scripts/test_openshell_smoke_wrapper.py
  • tests/scripts/test_openshell_version_tools.py
💤 Files with no reviewable changes (14)
  • frontends/ui/src/features/layout/components/FileSourcesTab.spec.tsx
  • frontends/ui/src/features/chat/components/ErrorBanner.tsx
  • frontends/ui/src/features/layout/components/ResearchPanel.spec.tsx
  • frontends/ui/src/features/chat/components/FileUploadBanner.tsx
  • frontends/ui/src/features/layout/components/CitationCard.spec.tsx
  • frontends/ui/src/features/layout/components/SourceCard.spec.tsx
  • frontends/ui/src/features/chat/components/index.ts
  • frontends/ui/src/features/chat/components/DeepResearchBanner.tsx
  • frontends/ui/src/features/layout/components/ReportCard.spec.tsx
  • frontends/ui/src/features/layout/components/SettingsPanel.spec.tsx
  • frontends/ui/src/features/chat/components/NoSourcesBanner.tsx
  • frontends/ui/src/features/layout/components/index.ts
  • frontends/ui/src/features/layout/components/DataConnectionsTab.spec.tsx
  • frontends/ui/src/features/layout/components/TasksTab.spec.tsx
📜 Review details
🧰 Additional context used
📓 Path-based instructions (14)
frontends/ui/**/*.{js,ts,jsx,tsx,vue}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Run npm lint, type-check, and build validation for UI changes in frontends/ui

Files:

  • frontends/ui/src/features/layout/components/SettingsPanel.tsx
  • frontends/ui/src/shared/lib/scroll.ts
  • frontends/ui/src/app/page.tsx
  • frontends/ui/src/features/layout/components/FileCard.tsx
  • frontends/ui/src/shared/lib/motion.spec.tsx
  • frontends/ui/src/shared/lib/scroll.spec.ts
  • frontends/ui/src/app/providers.tsx
  • frontends/ui/src/features/layout/data-sources.spec.ts
  • frontends/ui/src/features/layout/components/DataSourcesPanel.spec.tsx
  • frontends/ui/src/features/layout/components/TasksTab.tsx
  • frontends/ui/src/adapters/api/websocket-client.ts
  • frontends/ui/src/features/layout/components/DataConnectionsTab.tsx
  • frontends/ui/src/features/layout/components/TaskCard.tsx
  • frontends/ui/src/features/layout/components/CitationCard.tsx
  • frontends/ui/src/features/layout/components/ReportTab.tsx
  • frontends/ui/src/features/layout/data-sources.ts
  • frontends/ui/src/shared/components/Sources/SourceStrip.spec.tsx
  • frontends/ui/src/features/chat/components/UserMessage.tsx
  • frontends/ui/src/features/layout/index.ts
  • frontends/ui/src/features/layout/store.spec.ts
  • frontends/ui/src/features/layout/components/AgentsTab.tsx
  • frontends/ui/src/features/layout/components/ReportTab.spec.tsx
  • frontends/ui/src/features/layout/components/DataConnectionCard.tsx
  • frontends/ui/src/features/chat/components/ChatThinking.spec.tsx
  • frontends/ui/src/features/layout/types.ts
  • frontends/ui/src/shared/components/Sources/parse-references.spec.ts
  • frontends/ui/src/features/layout/components/AppBar.tsx
  • frontends/ui/src/features/layout/components/SourceCard.tsx
  • frontends/ui/src/features/layout/components/TaskCard.spec.tsx
  • frontends/ui/src/shared/components/Mermaid/MermaidBlock.spec.tsx
  • frontends/ui/src/features/layout/components/FileSourceCard.tsx
  • frontends/ui/src/features/layout/store.ts
  • frontends/ui/src/features/layout/components/FileSourceCard.spec.tsx
  • frontends/ui/src/features/chat/components/AgentResponse.tsx
  • frontends/ui/src/features/layout/components/ChatArea.autoscroll.spec.tsx
  • frontends/ui/src/features/chat/lib/deep-research-trace.ts
  • frontends/ui/src/features/chat/lib/session-activity.ts
  • frontends/ui/src/features/chat/store.spec.ts
  • frontends/ui/src/shared/components/Mermaid/MermaidBlock.tsx
  • frontends/ui/src/shared/components/CollapsibleBlock/CollapsibleBlock.tsx
  • frontends/ui/src/features/layout/components/InputArea.tsx
  • frontends/ui/src/shared/components/Sources/SourceStrip.tsx
  • frontends/ui/src/features/chat/components/AgentPrompt.spec.tsx
  • frontends/ui/src/features/chat/lib/intermediate-step-parser.spec.ts
  • frontends/ui/src/features/layout/components/ReportCard.tsx
  • frontends/ui/src/features/layout/components/ThinkingTab.tsx
  • frontends/ui/src/features/chat/store.ts
  • frontends/ui/src/features/layout/components/AppBar.spec.tsx
  • frontends/ui/src/features/layout/components/ChatArea.spec.tsx
  • frontends/ui/src/features/chat/components/ChatThinking.tsx
  • frontends/ui/src/features/layout/components/ThoughtCard.spec.tsx
  • frontends/ui/src/features/layout/components/ThinkingTab.spec.tsx
  • frontends/ui/src/features/layout/components/MainLayout.spec.tsx
  • frontends/ui/src/features/chat/lib/deep-research-trace.spec.ts
  • frontends/ui/src/features/layout/components/AgentCard.spec.tsx
  • frontends/ui/src/features/layout/components/AgentsTab.spec.tsx
  • frontends/ui/src/features/chat/hooks/use-websocket-chat.ts
  • frontends/ui/src/features/chat/components/AgentPrompt.tsx
  • frontends/ui/src/features/chat/lib/intermediate-step-parser.ts
  • frontends/ui/src/features/layout/components/MainLayout.tsx
  • frontends/ui/src/features/layout/components/DataSourcesPanel.tsx
  • frontends/ui/src/features/layout/components/AgentCard.tsx
  • frontends/ui/src/features/chat/types.ts
  • frontends/ui/src/features/layout/components/ResearchPanel.tsx
  • frontends/ui/src/features/chat/components/AgentResponse.spec.tsx
  • frontends/ui/src/features/layout/components/ThoughtCard.tsx
  • frontends/ui/src/features/layout/components/SessionsPanel.tsx
  • frontends/ui/src/features/layout/components/ChatArea.tsx
  • frontends/ui/src/features/layout/components/FileSourcesTab.tsx
  • frontends/ui/src/features/layout/components/SessionsPanel.spec.tsx
frontends/ui/**/*.{ts,tsx,jsx,js}

📄 CodeRabbit inference engine (AGENTS.md)

frontends/ui/**/*.{ts,tsx,jsx,js}: The UI is built with Next.js / React / TypeScript / Tailwind with KUI components; reuse existing KUI components and visual patterns rather than introducing new ones
Validate UI-affecting changes with npm run lint, npm run type-check, and npm run test:ci, and include a screenshot for visible changes

Files:

  • frontends/ui/src/features/layout/components/SettingsPanel.tsx
  • frontends/ui/src/shared/lib/scroll.ts
  • frontends/ui/src/app/page.tsx
  • frontends/ui/src/features/layout/components/FileCard.tsx
  • frontends/ui/src/shared/lib/motion.spec.tsx
  • frontends/ui/src/shared/lib/scroll.spec.ts
  • frontends/ui/src/app/providers.tsx
  • frontends/ui/src/features/layout/data-sources.spec.ts
  • frontends/ui/src/features/layout/components/DataSourcesPanel.spec.tsx
  • frontends/ui/src/features/layout/components/TasksTab.tsx
  • frontends/ui/src/adapters/api/websocket-client.ts
  • frontends/ui/src/features/layout/components/DataConnectionsTab.tsx
  • frontends/ui/src/features/layout/components/TaskCard.tsx
  • frontends/ui/src/features/layout/components/CitationCard.tsx
  • frontends/ui/src/features/layout/components/ReportTab.tsx
  • frontends/ui/src/features/layout/data-sources.ts
  • frontends/ui/src/shared/components/Sources/SourceStrip.spec.tsx
  • frontends/ui/src/features/chat/components/UserMessage.tsx
  • frontends/ui/src/features/layout/index.ts
  • frontends/ui/src/features/layout/store.spec.ts
  • frontends/ui/src/features/layout/components/AgentsTab.tsx
  • frontends/ui/src/features/layout/components/ReportTab.spec.tsx
  • frontends/ui/src/features/layout/components/DataConnectionCard.tsx
  • frontends/ui/src/features/chat/components/ChatThinking.spec.tsx
  • frontends/ui/src/features/layout/types.ts
  • frontends/ui/src/shared/components/Sources/parse-references.spec.ts
  • frontends/ui/src/features/layout/components/AppBar.tsx
  • frontends/ui/src/features/layout/components/SourceCard.tsx
  • frontends/ui/src/features/layout/components/TaskCard.spec.tsx
  • frontends/ui/src/shared/components/Mermaid/MermaidBlock.spec.tsx
  • frontends/ui/src/features/layout/components/FileSourceCard.tsx
  • frontends/ui/src/features/layout/store.ts
  • frontends/ui/src/features/layout/components/FileSourceCard.spec.tsx
  • frontends/ui/src/features/chat/components/AgentResponse.tsx
  • frontends/ui/src/features/layout/components/ChatArea.autoscroll.spec.tsx
  • frontends/ui/src/features/chat/lib/deep-research-trace.ts
  • frontends/ui/src/features/chat/lib/session-activity.ts
  • frontends/ui/src/features/chat/store.spec.ts
  • frontends/ui/src/shared/components/Mermaid/MermaidBlock.tsx
  • frontends/ui/src/shared/components/CollapsibleBlock/CollapsibleBlock.tsx
  • frontends/ui/src/features/layout/components/InputArea.tsx
  • frontends/ui/src/shared/components/Sources/SourceStrip.tsx
  • frontends/ui/src/features/chat/components/AgentPrompt.spec.tsx
  • frontends/ui/src/features/chat/lib/intermediate-step-parser.spec.ts
  • frontends/ui/src/features/layout/components/ReportCard.tsx
  • frontends/ui/src/features/layout/components/ThinkingTab.tsx
  • frontends/ui/src/features/chat/store.ts
  • frontends/ui/src/features/layout/components/AppBar.spec.tsx
  • frontends/ui/src/features/layout/components/ChatArea.spec.tsx
  • frontends/ui/src/features/chat/components/ChatThinking.tsx
  • frontends/ui/src/features/layout/components/ThoughtCard.spec.tsx
  • frontends/ui/src/features/layout/components/ThinkingTab.spec.tsx
  • frontends/ui/src/features/layout/components/MainLayout.spec.tsx
  • frontends/ui/src/features/chat/lib/deep-research-trace.spec.ts
  • frontends/ui/src/features/layout/components/AgentCard.spec.tsx
  • frontends/ui/src/features/layout/components/AgentsTab.spec.tsx
  • frontends/ui/src/features/chat/hooks/use-websocket-chat.ts
  • frontends/ui/src/features/chat/components/AgentPrompt.tsx
  • frontends/ui/src/features/chat/lib/intermediate-step-parser.ts
  • frontends/ui/src/features/layout/components/MainLayout.tsx
  • frontends/ui/src/features/layout/components/DataSourcesPanel.tsx
  • frontends/ui/src/features/layout/components/AgentCard.tsx
  • frontends/ui/src/features/chat/types.ts
  • frontends/ui/src/features/layout/components/ResearchPanel.tsx
  • frontends/ui/src/features/chat/components/AgentResponse.spec.tsx
  • frontends/ui/src/features/layout/components/ThoughtCard.tsx
  • frontends/ui/src/features/layout/components/SessionsPanel.tsx
  • frontends/ui/src/features/layout/components/ChatArea.tsx
  • frontends/ui/src/features/layout/components/FileSourcesTab.tsx
  • frontends/ui/src/features/layout/components/SessionsPanel.spec.tsx
frontends/ui/**/*

⚙️ CodeRabbit configuration file

frontends/ui/**/*: Review UI changes for strict TypeScript behavior, API contract alignment, auth/session handling, accessible controls,
resilient loading and error states, and report/chat state consistency. Prefer existing UI patterns and require tests
for changed user-visible workflows.

Files:

  • frontends/ui/src/features/layout/components/SettingsPanel.tsx
  • frontends/ui/src/shared/lib/scroll.ts
  • frontends/ui/src/app/page.tsx
  • frontends/ui/src/features/layout/components/FileCard.tsx
  • frontends/ui/src/shared/lib/motion.spec.tsx
  • frontends/ui/src/shared/lib/scroll.spec.ts
  • frontends/ui/src/app/providers.tsx
  • frontends/ui/src/features/layout/data-sources.spec.ts
  • frontends/ui/src/features/layout/components/DataSourcesPanel.spec.tsx
  • frontends/ui/src/features/layout/components/TasksTab.tsx
  • frontends/ui/src/adapters/api/websocket-client.ts
  • frontends/ui/src/features/layout/components/DataConnectionsTab.tsx
  • frontends/ui/src/features/layout/components/TaskCard.tsx
  • frontends/ui/src/features/layout/components/CitationCard.tsx
  • frontends/ui/src/features/layout/components/ReportTab.tsx
  • frontends/ui/src/features/layout/data-sources.ts
  • frontends/ui/src/shared/components/Sources/SourceStrip.spec.tsx
  • frontends/ui/src/features/chat/components/UserMessage.tsx
  • frontends/ui/src/features/layout/index.ts
  • frontends/ui/src/features/layout/store.spec.ts
  • frontends/ui/src/features/layout/components/AgentsTab.tsx
  • frontends/ui/src/features/layout/components/ReportTab.spec.tsx
  • frontends/ui/src/features/layout/components/DataConnectionCard.tsx
  • frontends/ui/src/features/chat/components/ChatThinking.spec.tsx
  • frontends/ui/src/features/layout/types.ts
  • frontends/ui/src/shared/components/Sources/parse-references.spec.ts
  • frontends/ui/src/features/layout/components/AppBar.tsx
  • frontends/ui/src/features/layout/components/SourceCard.tsx
  • frontends/ui/src/features/layout/components/TaskCard.spec.tsx
  • frontends/ui/src/shared/components/Mermaid/MermaidBlock.spec.tsx
  • frontends/ui/src/features/layout/components/FileSourceCard.tsx
  • frontends/ui/src/features/layout/store.ts
  • frontends/ui/src/features/layout/components/FileSourceCard.spec.tsx
  • frontends/ui/src/features/chat/components/AgentResponse.tsx
  • frontends/ui/src/features/layout/components/ChatArea.autoscroll.spec.tsx
  • frontends/ui/src/features/chat/lib/deep-research-trace.ts
  • frontends/ui/src/features/chat/lib/session-activity.ts
  • frontends/ui/src/features/chat/store.spec.ts
  • frontends/ui/src/shared/components/Mermaid/MermaidBlock.tsx
  • frontends/ui/src/shared/components/CollapsibleBlock/CollapsibleBlock.tsx
  • frontends/ui/src/features/layout/components/InputArea.tsx
  • frontends/ui/src/shared/components/Sources/SourceStrip.tsx
  • frontends/ui/src/features/chat/components/AgentPrompt.spec.tsx
  • frontends/ui/src/features/chat/lib/intermediate-step-parser.spec.ts
  • frontends/ui/src/features/layout/components/ReportCard.tsx
  • frontends/ui/src/features/layout/components/ThinkingTab.tsx
  • frontends/ui/src/features/chat/store.ts
  • frontends/ui/src/features/layout/components/AppBar.spec.tsx
  • frontends/ui/src/features/layout/components/ChatArea.spec.tsx
  • frontends/ui/src/features/chat/components/ChatThinking.tsx
  • frontends/ui/src/features/layout/components/ThoughtCard.spec.tsx
  • frontends/ui/src/features/layout/components/ThinkingTab.spec.tsx
  • frontends/ui/src/features/layout/components/MainLayout.spec.tsx
  • frontends/ui/src/features/chat/lib/deep-research-trace.spec.ts
  • frontends/ui/src/features/layout/components/AgentCard.spec.tsx
  • frontends/ui/src/features/layout/components/AgentsTab.spec.tsx
  • frontends/ui/src/features/chat/hooks/use-websocket-chat.ts
  • frontends/ui/src/features/chat/components/AgentPrompt.tsx
  • frontends/ui/src/features/chat/lib/intermediate-step-parser.ts
  • frontends/ui/src/features/layout/components/MainLayout.tsx
  • frontends/ui/src/features/layout/components/DataSourcesPanel.tsx
  • frontends/ui/src/features/layout/components/AgentCard.tsx
  • frontends/ui/src/features/chat/types.ts
  • frontends/ui/src/features/layout/components/ResearchPanel.tsx
  • frontends/ui/src/features/chat/components/AgentResponse.spec.tsx
  • frontends/ui/src/features/layout/components/ThoughtCard.tsx
  • frontends/ui/src/features/layout/components/SessionsPanel.tsx
  • frontends/ui/src/features/layout/components/ChatArea.tsx
  • frontends/ui/src/app/globals.css
  • frontends/ui/src/features/layout/components/FileSourcesTab.tsx
  • frontends/ui/src/features/layout/components/SessionsPanel.spec.tsx
docs/source/**/*

📄 CodeRabbit inference engine (AGENTS.md)

Update the docs under docs/source/ when behavior, configuration, or workflows change

Files:

  • docs/source/resources/troubleshooting.md
  • docs/source/deployment/index.md
  • docs/source/index.md
  • docs/source/examples/index.md
  • docs/source/deployment/production.md
  • docs/source/integration/rest-api.md
  • docs/source/examples/azure-ai-search.md
  • docs/source/architecture/agents/sandbox.md
  • docs/source/customization/configuration-reference.md
  • docs/source/customization/knowledge-layer.md
  • docs/source/deployment/openshell.md
{docs/**,README.md,CONTRIBUTING.md,SECURITY.md,CODE-OF-CONDUCT.md}

⚙️ CodeRabbit configuration file

{docs/**,README.md,CONTRIBUTING.md,SECURITY.md,CODE-OF-CONDUCT.md}: Review documentation for command accuracy, branch-name consistency, current CI and copy-pr-bot behavior, public
vs internal boundary clarity, stale examples, and links that no longer match the repository layout.

Files:

  • docs/source/resources/troubleshooting.md
  • docs/source/deployment/index.md
  • docs/source/index.md
  • docs/source/examples/index.md
  • docs/source/deployment/production.md
  • docs/source/integration/rest-api.md
  • docs/source/examples/azure-ai-search.md
  • docs/source/architecture/agents/sandbox.md
  • docs/source/customization/configuration-reference.md
  • docs/source/customization/knowledge-layer.md
  • docs/source/deployment/openshell.md
{.github/**,ci/**,.pre-commit-config.yaml,pyproject.toml,uv.lock}

⚙️ CodeRabbit configuration file

{.github/**,ci/**,.pre-commit-config.yaml,pyproject.toml,uv.lock}: Review automation and packaging changes for least-privilege permissions, pinned versions where appropriate,
copy-pr-bot pull-request/ branch behavior, reproducible uv/npm setup, secret handling, and consistency with
the documented validation matrix.

Files:

  • pyproject.toml
{deploy/**,configs/**}

⚙️ CodeRabbit configuration file

{deploy/**,configs/**}: Review deployment and config changes for secret separation, safe defaults, local-vs-production behavior, Helm and
Docker portability, and documentation parity. Flag committed credentials, environment-specific NVIDIA internals in
public defaults, and changes that make examples diverge from CI-tested paths.

Files:

  • configs/openshell/README.md
  • deploy/openshell/Dockerfile.aiq-demo
  • configs/config_web_azure_ai_search.yml
  • configs/openshell/aiq-research-policy.yaml
  • configs/config_openshell.yml
**/*.py

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Run ruff check and ruff format validation for Python code changes

**/*.py: Python code must be linted and formatted with Ruff using line length 120, target Python 3.11, rule sets E,F,W,I,PL,UP, and isort force-single-line configuration
Never commit secrets, tokens, or environment-specific hostnames; use environment variables and SecretStr instead, resolving API keys at runtime
Never print or log secret values, including in tool output or error messages
Missing-secret paths must degrade gracefully (stub/skip), not crash or leak
Do not hand-reformat unrelated code when making changes; match the existing import and formatting style

Files:

  • src/aiq_agent/agents/deep_researcher/register.py
  • scripts/openshell/smoke_openshell_isolation.py
  • scripts/openshell/check_openshell_readiness.py
  • scripts/openshell/check_versions.py
  • frontends/aiq_api/src/aiq_api/jobs/runner.py
  • tests/aiq_agent/jobs/test_runner.py
  • scripts/openshell/version_contract.py
  • sources/knowledge_layer/src/azure_ai_search/adapter.py
  • tests/aiq_agent/agents/deep_researcher/sandbox/test_openshell_live.py
src/aiq_agent/**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

src/aiq_agent/**/*.py: Respect authenticated data sources by honoring requires_auth, per-user token pass-through, and backend token validators; apply owner guardrails before loading protected report or artifact context into an agent
Do not weaken or bypass AuthMiddleware, validators, or auth gating without a prior design discussion

Files:

  • src/aiq_agent/agents/deep_researcher/register.py
src/aiq_agent/agents/**/*

⚙️ CodeRabbit configuration file

src/aiq_agent/agents/**/*: Review agent changes for research workflow correctness, graph state transitions, prompt/tool contracts,
HITL behavior, and failure handling. Flag changes that weaken source attribution, report generation,
async cancellation, checkpointing, or data-source selection without focused tests and docs.

Files:

  • src/aiq_agent/agents/deep_researcher/register.py
{src/aiq_agent/fastapi_extensions/**,frontends/aiq_api/src/aiq_api/**}

⚙️ CodeRabbit configuration file

{src/aiq_agent/fastapi_extensions/**,frontends/aiq_api/src/aiq_api/**}: Treat API, auth, and job-runner changes as externally visible contracts. Check authorization boundaries,
request tracing, async job lifecycle, websocket reconnect behavior, error responses, and cross-user data isolation.
Require tests for route behavior, access decisions, and job state transitions when those surfaces change.

Files:

  • frontends/aiq_api/src/aiq_api/jobs/runner.py
**/*test*.py

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Run pytest for all behavior changes in Python code

Files:

  • tests/aiq_agent/jobs/test_runner.py
  • tests/aiq_agent/agents/deep_researcher/sandbox/test_openshell_live.py
sources/**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

New tools and data sources must be NAT functions registered with @register_function decorator

Files:

  • sources/knowledge_layer/src/azure_ai_search/adapter.py
{src/aiq_agent/knowledge/**,sources/**}

⚙️ CodeRabbit configuration file

{src/aiq_agent/knowledge/**,sources/**}: Review data-source and knowledge-layer changes for optional dependency boundaries, external API error handling,
retry/rate-limit behavior, deterministic tests, and registration consistency. New source packages should include
package metadata, plugin registration when applicable, and source-level tests.

Files:

  • sources/knowledge_layer/src/azure_ai_search/adapter.py
🪛 ast-grep (0.44.1)
scripts/openshell/smoke_openshell_isolation.py

[error] 81-86: Command coming from incoming request
Context: subprocess.run( # noqa: S603 - fixed argv, no shell, operator-selected interpreter
_command(),
cwd=_REPO_ROOT,
env=_environment(args),
check=False,
)
Note: [CWE-78] Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection').

(subprocess-from-request)

scripts/openshell/check_openshell_readiness.py

[error] 53-59: Command coming from incoming request
Context: subprocess.run(
[str(binary), "--version"],
check=False,
capture_output=True,
text=True,
timeout=10,
)
Note: [CWE-78] Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection').

(subprocess-from-request)

scripts/openshell/check_versions.py

[error] 46-46: Use of unsanitized data to create processes
Context: subprocess.run(command, check=False, capture_output=True, text=True, timeout=15)
Note: [CWE-78] Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection').

(os-system-unsanitized-data)


[error] 46-46: Command coming from incoming request
Context: subprocess.run(command, check=False, capture_output=True, text=True, timeout=15)
Note: [CWE-78] Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection').

(subprocess-from-request)


[info] 226-226: use jsonify instead of json.dumps for JSON output
Context: json.dumps(asdict(report), sort_keys=True)
Note: [CWE-116] Improper Encoding or Escaping of Output.

(use-jsonify)

scripts/openshell/version_contract.py

[info] 76-76: use jsonify instead of json.dumps for JSON output
Context: json.dumps(asdict(contract), sort_keys=True)
Note: [CWE-116] Improper Encoding or Escaping of Output.

(use-jsonify)

sources/knowledge_layer/src/azure_ai_search/adapter.py

[info] 161-161: use jsonify instead of json.dumps for JSON output
Context: json.dumps(marker, separators=(",", ":"), sort_keys=True)
Note: [CWE-116] Improper Encoding or Escaping of Output.

(use-jsonify)


[info] 255-255: use jsonify instead of json.dumps for JSON output
Context: json.dumps(payload, default=_json_default, ensure_ascii=False, separators=(",", ":"))
Note: [CWE-116] Improper Encoding or Escaping of Output.

(use-jsonify)


[info] 651-651: use jsonify instead of json.dumps for JSON output
Context: json.dumps(merged_metadata, separators=(",", ":"), sort_keys=True)
Note: [CWE-116] Improper Encoding or Escaping of Output.

(use-jsonify)


[info] 692-692: use jsonify instead of json.dumps for JSON output
Context: json.dumps(metadata, separators=(",", ":"), sort_keys=True)
Note: [CWE-116] Improper Encoding or Escaping of Output.

(use-jsonify)


[info] 761-761: use jsonify instead of json.dumps for JSON output
Context: json.dumps(file_metadata, separators=(",", ":"), sort_keys=True)
Note: [CWE-116] Improper Encoding or Escaping of Output.

(use-jsonify)


[info] 950-950: use jsonify instead of json.dumps for JSON output
Context: json.dumps(metadata, separators=(",", ":"), sort_keys=True)
Note: [CWE-116] Improper Encoding or Escaping of Output.

(use-jsonify)

tests/aiq_agent/agents/deep_researcher/sandbox/test_openshell_live.py

[info] 408-408: use jsonify instead of json.dumps for JSON output
Context: json.dumps(events, default=str)
Note: [CWE-116] Improper Encoding or Escaping of Output.

(use-jsonify)

🪛 LanguageTool
scripts/README.md

[style] ~88-~88: Consider a different adjective to strengthen your wording.
Context: ...Mode Starts the NAT FastAPI server for deep research with async job support. ```ba...

(DEEP_PROFOUND)

docs/source/deployment/openshell.md

[style] ~48-~48: Consider a different adjective to strengthen your wording.
Context: ...penShell executes code generated during deep research. AI-Q orchestration, inference...

(DEEP_PROFOUND)

🪛 Stylelint (17.14.0)
frontends/ui/src/app/globals.css

[error] 130-130: Expected "optimizeLegibility" to be "optimizelegibility" (value-keyword-case)

(value-keyword-case)

@Manushpm8
Manushpm8 force-pushed the feat/ui-chat-look branch from ebd4826 to 860114e Compare July 16, 2026 04:07

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Inline review comments failed to post. This is likely due to GitHub's internal server error or limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.

🛑 Comments failed to post (33)
docs/source/customization/configuration-reference.md (1)

605-605: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Correct the configuration-profile count.

The introduction says there are nine profiles, but this table now lists ten after adding the Azure profile. Update the count to avoid misleading operators.

As per path instructions, review documentation for “stale examples”.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/source/customization/configuration-reference.md` at line 605, Update the
configuration-profile count in the introduction of configuration-reference.md
from nine to ten, matching the ten profiles listed in the table, including
configs/config_web_azure_ai_search.yml. Review nearby documentation for stale
examples of the old count and update only those references.

Source: Path instructions

docs/source/customization/knowledge-layer.md (1)

488-489: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Complete the environment-variable table for Azure AI Search.

Add AZURE_SEARCH_ENDPOINT, AZURE_SEARCH_API_KEY, AIQ_AZURE_SEARCH_INDEX_PREFIX, and AIQ_EMBED_DIM. Also include Azure in the existing AIQ_EMBED_MODEL/AIQ_EMBED_BASE_URL row; otherwise this central reference contradicts Lines 181-189.

As per path instructions, review documentation for “command accuracy” and “stale examples.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/source/customization/knowledge-layer.md` around lines 488 - 489, Update
the environment-variable table in the knowledge-layer customization
documentation to include AZURE_SEARCH_ENDPOINT, AZURE_SEARCH_API_KEY,
AIQ_AZURE_SEARCH_INDEX_PREFIX, and AIQ_EMBED_DIM. Extend the existing
AIQ_EMBED_MODEL/AIQ_EMBED_BASE_URL entry to cover Azure AI Search, keeping the
table consistent with the Azure configuration documented in the earlier section
and correcting any stale or inaccurate examples encountered there.

Source: Path instructions

docs/source/deployment/openshell.md (1)

203-211: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Make the production command safe for external gateways.

The text says --reuse-existing must be used unless the launcher may start a local packaged service, but the canonical command omits it. External-gateway operators will therefore run the wrong lifecycle mode.

Proposed correction
 ./scripts/openshell/start_openshell_gateway.sh \
   --gateway-name openshell \
+  --reuse-existing \
   --image-name aiq-openshell-demo:latest \
   --policy-file configs/openshell/generated/aiq-openshell-policy.yaml

Document omitting the flag as the local packaged-service variant.

As per path instructions, review documentation for “command accuracy” and current deployment behavior.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

execution, and deletion capabilities. Omit `--reuse-existing` only when the gateway is a local packaged
service that the launcher may start through systemd.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/source/deployment/openshell.md` around lines 203 - 211, Update the
canonical openshell gateway command in the deployment documentation to include
--reuse-existing for external gateways. Clearly label any command that omits
this flag as the local packaged-service variant where the launcher may start
systemd, and keep the documented lifecycle behavior consistent with the
surrounding guidance.

Source: Path instructions

frontends/ui/src/app/globals.css (2)

88-88: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Increase the subtle-text token contrast.

These colors provide approximately 2.6:1 contrast in light mode and 3.1:1 in dark mode. They are used for small labels and metadata that require at least 4.5:1 contrast.

Validate both theme values against their base and raised surfaces after adjustment.

As per path instructions, review UI changes for accessible controls and require tests for changed user-visible workflows.

Also applies to: 113-113

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontends/ui/src/app/globals.css` at line 88, Update the light and dark theme
values for --text-color-subtle to achieve at least 4.5:1 contrast against their
respective base and raised surfaces, then validate both theme combinations. Add
or update tests covering the affected user-visible UI workflows and accessible
controls.

Source: Path instructions


130-130: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Use Stylelint’s canonical keyword casing.

The supplied validation reports this declaration as an error.

Proposed fix
-  text-rendering: optimizeLegibility;
+  text-rendering: optimizelegibility;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

  text-rendering: optimizelegibility;
🧰 Tools
🪛 Stylelint (17.14.0)

[error] 130-130: Expected "optimizeLegibility" to be "optimizelegibility" (value-keyword-case)

(value-keyword-case)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontends/ui/src/app/globals.css` at line 130, Update the text-rendering
declaration to use Stylelint’s canonical casing for the optimizeLegibility
keyword, while preserving the existing property and value.

Source: Linters/SAST tools

frontends/ui/src/features/chat/components/AgentPrompt.tsx (2)

143-154: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Use the prompt type instead of relying on exact English copy.

A type="approval" prompt whose wording differs from APPROVAL_PROMPT_RE becomes a clarification prompt with text/cancel controls. Preserve compatibility fallback if needed, but honor the explicit contract first.

Proposed fix
 export const AgentPrompt: FC<AgentPromptProps> = ({
-  type: _type,
+  type,
 ...
-  const isApprovalPrompt = APPROVAL_PROMPT_RE.test(content)
+  const isApprovalPrompt = type === 'approval' || APPROVAL_PROMPT_RE.test(content)

Add coverage for an approval type whose content does not contain the legacy phrase.

As per path instructions, review UI changes for “API contract alignment” and “require tests for changed user-visible workflows.”

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

export const AgentPrompt: FC<AgentPromptProps> = ({
  type,
  content,
  options = [],
  isResponded = false,
  response,
  variant = 'default',
}) => {
  const respondToInteractionFn = useChatStore((state) => state.respondToInteractionFn)
  const isApprovalPrompt = type === 'approval' || APPROVAL_PROMPT_RE.test(content)
  const canRespond = !isResponded && !!respondToInteractionFn
  const showApprovalButtons = isApprovalPrompt && canRespond
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontends/ui/src/features/chat/components/AgentPrompt.tsx` around lines 143 -
154, Update AgentPrompt to use the destructured prompt type as the primary
approval determination, treating type="approval" as an approval prompt
regardless of content; retain the APPROVAL_PROMPT_RE check only as a
compatibility fallback if required. Add coverage for an approval-typed prompt
whose content lacks the legacy phrase, verifying the approval controls are
rendered.

Source: Path instructions


200-237: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Do not let global shortcuts override focused controls.

When keyboard focus is on Reject, pressing Enter reaches this window listener, calls handleApprove(), and prevents the button’s native reject activation. Ignore interactive event targets or scope shortcuts to the prompt container; add a regression test activating Reject with Enter.

As per path instructions, review UI changes for “accessible controls” and require tests for changed workflows.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontends/ui/src/features/chat/components/AgentPrompt.tsx` around lines 200 -
237, The global keydown handler in the AgentPrompt useEffect must not intercept
activation of focused interactive controls, especially the Reject button. Extend
isTyping or otherwise detect focused buttons and other interactive targets
before handling shortcuts, preserving native Enter/activation behavior; add a
regression test that focuses Reject and activates it with Enter, verifying
rejection occurs instead of handleApprove.

Source: Path instructions

frontends/ui/src/features/chat/components/ChatThinking.tsx (3)

66-71: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Normalize rounded seconds before splitting minutes.

For example, 119600ms renders as 1m 60s. Round once and use modulo arithmetic.

Proposed fix
 const formatDuration = (ms: number): string => {
   const seconds = Math.max(0, ms) / 1000
   if (seconds < 60) return `${seconds.toFixed(1)}s`
-  const m = Math.floor(seconds / 60)
-  const s = Math.round(seconds % 60)
+  const totalSeconds = Math.round(seconds)
+  const m = Math.floor(totalSeconds / 60)
+  const s = totalSeconds % 60
   return `${m}m ${s}s`
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

const formatDuration = (ms: number): string => {
  const seconds = Math.max(0, ms) / 1000
  if (seconds < 60) return `${seconds.toFixed(1)}s`
  const totalSeconds = Math.round(seconds)
  const m = Math.floor(totalSeconds / 60)
  const s = totalSeconds % 60
  return `${m}m ${s}s`
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontends/ui/src/features/chat/components/ChatThinking.tsx` around lines 66 -
71, Update formatDuration to round the non-negative duration to whole seconds
before calculating minutes and remaining seconds, then derive both values using
quotient and modulo arithmetic so carry-over values such as 119600ms render as
2m 0s while sub-minute durations retain the existing one-decimal format.

179-198: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Do not deduplicate calls using only their display label.

This pass removes every nested row sharing a top-level label before checking isKnownTool or argSummary. Repeated searches with different inputs can therefore be dropped or have one call’s arguments assigned to another; non-tool rows can also be removed.

Prefer preserving ambiguous rows and let the exact label/input grouping below deduplicate identifiable calls:

Safe fallback
-  const topLevelLabels = new Set(
-    steps.filter((s) => s.isTopLevel).map((s) => getToolLabel(s.functionName).label)
-  )
-  const nestedSummaries = new Map<string, string>()
-  for (const step of steps) {
-    if (step.isTopLevel || !step.argSummary) continue
-    const label = getToolLabel(step.functionName).label
-    const existing = nestedSummaries.get(label)
-    if (!existing || step.argSummary.length > existing.length) {
-      nestedSummaries.set(label, step.argSummary)
-    }
-  }
-  const enriched = steps
-    .filter((s) => s.isTopLevel || !topLevelLabels.has(getToolLabel(s.functionName).label))
-    .map((step) => {
-      if (!step.isTopLevel) return step
-      const nestedSummary = nestedSummaries.get(getToolLabel(step.functionName).label)
-      if (!nestedSummary || nestedSummary.length <= (step.argSummary?.length ?? 0)) return step
-      return { ...step, argSummary: nestedSummary }
-    })
+  const enriched = steps

Add regression cases for same-label calls with different arguments and same-label non-tool rows.

As per path instructions, UI changes must preserve report/chat state consistency and include focused tests.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

  const enriched = steps
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontends/ui/src/features/chat/components/ChatThinking.tsx` around lines 179
- 198, Replace the label-only filtering and argument merging in the
topLevelLabels/nestedSummaries/enriched flow, since same-label calls may have
different inputs and non-tool rows must not be removed. Preserve ambiguous rows
and defer deduplication to the existing exact label/input grouping logic below,
while retaining identifiable-call deduplication. Add focused regression tests
for same-label calls with different arguments and same-label non-tool rows,
ensuring report and chat state remain consistent.

Source: Path instructions


333-337: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Propagate terminal phase failures to unfinished child calls.

An incomplete child under an errored or interrupted phase currently renders as done. Pass the parent state so unfinished calls retain the correct terminal outcome.

Proposed fix
-const childState = (child: ThinkingStep, isLastInRunningPhase: boolean): NodeState => {
+const childState = (
+  child: ThinkingStep,
+  parentState: NodeState,
+  isLastChild: boolean
+): NodeState => {
   if (child.status === 'error') return 'error'
   if (child.status === 'success' || child.isComplete) return 'done'
-  return isLastInRunningPhase ? 'running' : 'done'
+  if (parentState === 'running') return isLastChild ? 'running' : 'done'
+  if (parentState === 'error') return 'error'
+  if (parentState === 'interrupted') return 'interrupted'
+  if (parentState === 'waiting') return 'waiting'
+  return 'done'
 }
- status={childState(child, state === 'running' && childIndex === childCount - 1)}
+ status={childState(child, state, childIndex === childCount - 1)}

Add coverage for incomplete children beneath error and interrupted phases.

As per path instructions, UI changes must preserve report/chat state consistency and include focused tests.

Also applies to: 512-519

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontends/ui/src/features/chat/components/ChatThinking.tsx` around lines 333
- 337, Update childState and its callers to accept the parent phase state,
propagating error or interrupted terminal outcomes to children that are not
complete instead of marking them done. Preserve child-level error/success
handling and running-phase behavior for active phases. Add focused tests
covering incomplete children under errored and interrupted phases while
preserving report/chat state consistency.

Source: Path instructions

frontends/ui/src/features/chat/lib/deep-research-trace.ts (1)

35-56: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Deduplicate trace updates by event ID, not call contents.

Distinct calls with the same function and arguments are currently merged. Fold updates can also leave stale explanation content. Use the tool/fold ID as identity and replace newer snapshots of that ID.

Proposed fix
   const sameCall = (a: ThinkingStep, b: ThinkingStep): boolean =>
-    a.isTopLevel === b.isTopLevel &&
-    a.functionName === b.functionName &&
-    (a.argSummary ?? '') === (b.argSummary ?? '')
+    a.id === b.id
   const sameFold = (a: ThinkingStep, b: ThinkingStep): boolean =>
-    a.functionName === b.functionName && a.content === b.content
+    a.id === b.id
...
     if (isFold(step)) {
       const prev = out[out.length - 1]
-      if (prev && isFold(prev) && sameFold(prev, step)) continue
+      if (prev && isFold(prev) && sameFold(prev, step)) {
+        out[out.length - 1] = step
+        continue
+      }

Add regression coverage for distinct IDs with identical inputs and updated snapshots sharing one ID.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

  const sameCall = (a: ThinkingStep, b: ThinkingStep): boolean =>
    a.id === b.id
  const sameFold = (a: ThinkingStep, b: ThinkingStep): boolean =>
    a.id === b.id

  let lastToolIndex = -1
  for (const step of steps) {
    if (step.category === 'tools') {
      const lastTool = lastToolIndex >= 0 ? out[lastToolIndex] : undefined
      if (lastTool && sameCall(lastTool, step)) {
        out[lastToolIndex] = { ...step, id: lastTool.id }
      } else {
        out.push(step)
        lastToolIndex = out.length - 1
      }
      continue
    }
    if (isFold(step)) {
      const prev = out[out.length - 1]
      if (prev && isFold(prev) && sameFold(prev, step)) {
        out[out.length - 1] = step
        continue
      }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontends/ui/src/features/chat/lib/deep-research-trace.ts` around lines 35 -
56, Update the trace deduplication logic in the step-processing flow, including
sameCall, sameFold, and lastToolIndex, to use each tool or fold step’s event ID
as identity rather than function, arguments, or content. Replace an existing
snapshot when the ID matches, while preserving distinct steps with identical
inputs and ensuring newer snapshots replace stale explanation content. Add
regression coverage for distinct IDs with identical inputs and updated snapshots
sharing one ID.
frontends/ui/src/features/layout/components/AgentCard.spec.tsx (1)

219-225: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Cover the non-expandable ARIA state.

Extend the disabled/no-content case to assert aria-expanded="false" and no aria-controls, preventing references to an unrendered region.

As per path instructions, review UI changes for “accessible controls” and require tests for changed workflows.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontends/ui/src/features/layout/components/AgentCard.spec.tsx` around lines
219 - 225, Extend the disabled/no-content AgentCard test to verify its
accessible button state: assert aria-expanded is "false" and aria-controls is
absent when no content region is rendered. Keep the existing expandable-case
assertions unchanged.

Source: Path instructions

frontends/ui/src/features/layout/components/AgentCard.tsx (1)

102-108: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Correct the disabled AgentCard expansion semantics. A contentless card currently claims to be expanded and references an absent controlled region.

  • frontends/ui/src/features/layout/components/AgentCard.tsx#L102-L108: set aria-expanded to false and omit aria-controls when canExpand is false.
  • frontends/ui/src/features/layout/components/AgentCard.spec.tsx#L219-L225: assert those attributes for the no-content case.

As per path instructions, review UI changes for accessible controls and require tests for changed workflows.

📍 Affects 2 files
  • frontends/ui/src/features/layout/components/AgentCard.tsx#L102-L108 (this comment)
  • frontends/ui/src/features/layout/components/AgentCard.spec.tsx#L219-L225
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontends/ui/src/features/layout/components/AgentCard.tsx` around lines 102 -
108, Update the AgentCard button’s accessibility attributes so aria-expanded is
false and aria-controls is omitted whenever canExpand is false, while preserving
the existing expanded state and controlled-region reference for expandable
cards. Add assertions in
frontends/ui/src/features/layout/components/AgentCard.spec.tsx:219-225 for the
no-content case;
frontends/ui/src/features/layout/components/AgentCard.tsx:102-108 requires the
implementation change.

Source: Path instructions

frontends/ui/src/features/layout/components/AppBar.spec.tsx (1)

105-122: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Cover both toggle directions.

Add cases where rightPanel is already data-sources and where theme is dark; assert closeRightPanel() and setTheme('light') respectively.

As per path instructions, “Prefer existing UI patterns and require tests for changed user-visible workflows.” <path_instructions>

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontends/ui/src/features/layout/components/AppBar.spec.tsx` around lines 105
- 122, Add tests in the AppBar interaction suite covering the already-open
data-sources state and the dark-theme state. Configure the relevant mocked state
before rendering AppBar, click the existing Add Sources and theme-toggle
buttons, and assert mockCloseRightPanel and mockSetTheme are called with 'light'
respectively, while preserving the existing opposite-direction cases.

Source: Path instructions

frontends/ui/src/features/layout/components/DataSourcesPanel.tsx (3)

220-245: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Locate the component and related tests.
git ls-files 'frontends/ui/src/features/layout/components/DataSourcesPanel.tsx' \
             'frontends/ui/src/features/layout/components/*DataSources*' \
             'frontends/ui/src/features/layout/**/__tests__/*' \
             'frontends/ui/src/features/layout/**/*.test.*' \
             'frontends/ui/src/features/layout/**/*.spec.*'

# Search for focus handling in the feature area.
rg -n --hidden --glob 'frontends/ui/src/features/layout/**' \
  'focus|focused|restoreFocus|triggerRef|buttonRef|aria-hidden|onClose|onOpen|useRef|useEffect' \
  frontends/ui/src/features/layout

# Show a compact AST outline for the target component if present.
ast-grep outline frontends/ui/src/features/layout/components/DataSourcesPanel.tsx --view expanded || true

Repository: NVIDIA-AI-Blueprints/aiq

Length of output: 16704


🏁 Script executed:

#!/bin/bash
set -euo pipefail

file='frontends/ui/src/features/layout/components/DataSourcesPanel.tsx'

echo "=== FILE EXISTS ==="
git ls-files "$file"

echo "=== KEY EXCERPT A ==="
sed -n '1,340p' "$file" | cat -n | sed -n '1,340p'

echo "=== TEST SEARCH ==="
rg -n --hidden --glob 'frontends/ui/src/features/layout/**/*.{test,spec}.{ts,tsx,js,jsx}' \
  'DataSourcesPanel|data sources|focus|aria-hidden|trigger' frontends/ui/src/features/layout || true

Repository: NVIDIA-AI-Blueprints/aiq

Length of output: 25165


🏁 Script executed:

#!/bin/bash
set -euo pipefail

file='frontends/ui/src/features/layout/components/DataSourcesPanel.tsx'

echo "=== 180-310 ==="
sed -n '180,310p' "$file" | cat -n

echo "=== 310-END ==="
sed -n '310,420p' "$file" | cat -n

Repository: NVIDIA-AI-Blueprints/aiq

Length of output: 11426


🏁 Script executed:

#!/bin/bash
set -euo pipefail

rg -n --hidden --glob 'frontends/ui/src/**/*.{ts,tsx,js,jsx}' \
  'focus\(\)|restore.*focus|return.*focus|triggerRef|buttonRef|onClose.*focus|close.*focus' \
  frontends/ui/src | head -n 200

Repository: NVIDIA-AI-Blueprints/aiq

Length of output: 1139


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== STORE: close/open panel logic ==="
rg -n --hidden --glob 'frontends/ui/src/features/layout/**' \
  'closeRightPanel|rightPanel|data-sources|open.*data sources|add data sources|setRightPanel|openRightPanel' \
  frontends/ui/src/features/layout/store* frontends/ui/src/features/layout/components/AppBar.tsx frontends/ui/src/features/layout/components/MainLayout.tsx frontends/ui/src/features/layout/components/DataSourcesPanel.spec.tsx

echo
echo "=== APPBAR EXCERPT ==="
sed -n '1,420p' frontends/ui/src/features/layout/components/AppBar.tsx | cat -n | sed -n '1,420p'

echo
echo "=== STORE EXCERPT ==="
sed -n '1,360p' frontends/ui/src/features/layout/store.ts | cat -n | sed -n '1,360p'

echo
echo "=== DATASOURCESPANEL SPEC CLOSE AREA ==="
sed -n '1,340p' frontends/ui/src/features/layout/components/DataSourcesPanel.spec.tsx | cat -n | sed -n '1,340p'

Repository: NVIDIA-AI-Blueprints/aiq

Length of output: 50380


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== STORE SEARCH ==="
rg -n --hidden --glob 'frontends/ui/src/features/layout/store.ts' \
  'closeRightPanel|rightPanel|setRightPanel|openRightPanel|data-sources' \
  frontends/ui/src/features/layout/store.ts

echo
echo "=== APPBAR SEARCH ==="
rg -n --hidden --glob 'frontends/ui/src/features/layout/components/AppBar.tsx' \
  'data sources|add data sources|rightPanel|closeRightPanel|openRightPanel|setRightPanel|button|focus|ref' \
  frontends/ui/src/features/layout/components/AppBar.tsx

echo
echo "=== DATA SOURCES SPEC SEARCH ==="
rg -n --hidden --glob 'frontends/ui/src/features/layout/components/DataSourcesPanel.spec.tsx' \
  'close|focus|aria-hidden|trigger|button|open|panel' \
  frontends/ui/src/features/layout/components/DataSourcesPanel.spec.tsx

Repository: NVIDIA-AI-Blueprints/aiq

Length of output: 4740


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== STORE (1-260) ==="
sed -n '1,260p' frontends/ui/src/features/layout/store.ts | cat -n | sed -n '1,260p'

echo
echo "=== APPBAR (240-360) ==="
sed -n '240,360p' frontends/ui/src/features/layout/components/AppBar.tsx | cat -n | sed -n '240,360p'

echo
echo "=== DATASOURCESPANEL SPEC (1-340) ==="
sed -n '1,340p' frontends/ui/src/features/layout/components/DataSourcesPanel.spec.tsx | cat -n | sed -n '1,340p'

Repository: NVIDIA-AI-Blueprints/aiq

Length of output: 26374


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
from pathlib import Path

files = [
    ('frontends/ui/src/features/layout/store.ts', 1, 220),
    ('frontends/ui/src/features/layout/components/AppBar.tsx', 240, 360),
    ('frontends/ui/src/features/layout/components/DataSourcesPanel.spec.tsx', 1, 340),
]
for path, start, end in files:
    print(f"=== {path} {start}-{end} ===")
    lines = Path(path).read_text().splitlines()
    for i in range(start-1, min(end, len(lines))):
        print(f"{i+1:4d} {lines[i]}")
    print()
PY

Repository: NVIDIA-AI-Blueprints/aiq

Length of output: 28952


Return focus to the Add data sources trigger on close

The close button leaves focus inside an aria-hidden panel. Restore focus to the AppBar trigger when dismissing the panel, and add a regression test for the close flow.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontends/ui/src/features/layout/components/DataSourcesPanel.tsx` around
lines 220 - 245, Update the DataSourcesPanel close flow to move focus back to
the AppBar “Add data sources” trigger before or when the panel becomes
aria-hidden, rather than leaving focus inside the panel. Reuse the trigger’s
existing ref or accessible identifier, and add a regression test that opens the
panel, closes it, and verifies focus returns to that trigger.

Source: Path instructions


316-365: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Avoid nesting the switch inside another interactive control.

The role="button" row and its child Switch create duplicate keyboard stops and conflicting semantics for one action. Keep the row non-interactive and use the KUI Switch as the sole control.

As per path instructions, UI changes must be reviewed for accessible controls.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontends/ui/src/features/layout/components/DataSourcesPanel.tsx` around
lines 316 - 365, Remove the row’s interactive button semantics and handlers from
the Flex container, including role, tabIndex, click, keyboard, and
button-specific ARIA attributes. Keep the KUI Switch as the sole interactive
control, preserving its checked state, disabled behavior, accessible label, and
handleToggleAll callback; retain suitable visual styling without relying on
interactive-row behavior.

Source: Path instructions


388-395: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Pass the authentication token when retrying.

This retry uses fetchDataSources() while the other refresh path passes idToken; protected-source retries can therefore repeat an unauthenticated request. Use fetchDataSources(idToken) and test token forwarding.

As per path instructions, UI changes must preserve auth/session handling and API contract alignment.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontends/ui/src/features/layout/components/DataSourcesPanel.tsx` around
lines 388 - 395, Update the Retry button’s onClick handler in DataSourcesPanel
to call fetchDataSources with the current idToken, matching the existing
authenticated refresh path and preserving the API contract. Add or update the
relevant test to verify the token is forwarded on retry.

Source: Path instructions

frontends/ui/src/features/layout/components/MainLayout.spec.tsx (1)

121-125: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Assert that the Data Sources panel is absent.

The test name promises both panels are hidden, but it only checks sessions-panel. Add the corresponding data-sources-panel assertion.

Proposed fix
 expect(screen.getByTestId('app-bar')).toBeInTheDocument()
 expect(screen.queryByTestId('sessions-panel')).not.toBeInTheDocument()
+expect(screen.queryByTestId('data-sources-panel')).not.toBeInTheDocument()

As per path instructions, “require tests for changed user-visible workflows.”

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

  test('hides the sessions sidebar and data sources panel when unauthenticated', () => {
    render(<MainLayout />)

    expect(screen.getByTestId('app-bar')).toBeInTheDocument()
    expect(screen.queryByTestId('sessions-panel')).not.toBeInTheDocument()
    expect(screen.queryByTestId('data-sources-panel')).not.toBeInTheDocument()
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontends/ui/src/features/layout/components/MainLayout.spec.tsx` around lines
121 - 125, Update the unauthenticated MainLayout test to also assert that the
element identified by data-sources-panel is absent, matching the existing
sessions-panel assertion and the test’s stated coverage.

Source: Path instructions

frontends/ui/src/features/layout/components/SessionsPanel.tsx (2)

303-317: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Restore visible keyboard focus on sidebar inputs.

Both inputs use outline-none without a replacement focus style, leaving keyboard users without a visible focus indicator.

  • frontends/ui/src/features/layout/components/SessionsPanel.tsx#L303-L317: add a focus-visible ring or the existing KUI input pattern to the search input.
  • frontends/ui/src/features/layout/components/SessionsPanel.tsx#L612-L622: add the same visible focus treatment to the rename input.

As per path instructions, review UI changes for accessible controls.

📍 Affects 1 file
  • frontends/ui/src/features/layout/components/SessionsPanel.tsx#L303-L317 (this comment)
  • frontends/ui/src/features/layout/components/SessionsPanel.tsx#L612-L622
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontends/ui/src/features/layout/components/SessionsPanel.tsx` around lines
303 - 317, Restore a visible keyboard focus indicator on both inputs in
SessionsPanel.tsx: add the existing KUI input focus treatment or an equivalent
focus-visible ring to the search input at lines 303-317 and the rename input at
lines 612-622, replacing the ineffective outline-none-only styling while
preserving their current behavior.

Source: Path instructions


418-424: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Apply the navigation guard to the empty-state action.

During streaming or pending HITL, the top “New Session” action is disabled, but this button still invokes handleNewSession. An active unsaved session with no named history can therefore bypass the guard.

Proposed fix
-<Button kind="secondary" size="small" onClick={handleNewSession} className="mt-1">
+<Button
+  kind="secondary"
+  size="small"
+  onClick={handleNewSession}
+  disabled={isNavigationBlocked}
+  className="mt-1"
+>

Add a regression test for the empty-state button during streaming and pending HITL. As per path instructions, review session handling and require tests for changed user-visible workflows.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

                {!(searchOpen && searchQuery.trim()) && (
                  <Button
                    kind="secondary"
                    size="small"
                    onClick={handleNewSession}
                    disabled={isNavigationBlocked}
                    className="mt-1"
                  >
                    <Flex align="center" gap="2">
                      <Plus className="h-4 w-4" />
                      <Text kind="label/bold/sm">Start a new session</Text>
                    </Flex>
                  </Button>
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontends/ui/src/features/layout/components/SessionsPanel.tsx` around lines
418 - 424, Apply the same streaming and pending-HITL navigation guard used by
the top “New Session” action to the empty-state button’s handleNewSession path
in SessionsPanel. Preserve the existing search visibility condition, and add
regression coverage verifying the empty-state button cannot navigate during
streaming or pending HITL.

Source: Path instructions

frontends/ui/src/features/layout/components/ThinkingTab.tsx (1)

97-106: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Use a distinct empty state for Cited (0). The current branch conflates a zero-match filter with having no sources.

  • frontends/ui/src/features/layout/components/ThinkingTab.tsx#L97-L106: render “No cited sources yet” when uncited sources exist but the Cited filter is empty.
  • frontends/ui/src/features/layout/components/ThinkingTab.spec.tsx#L86-L120: add a regression test containing only uncited sources and select Cited (0).

As per path instructions, review UI changes for resilient states, state consistency, and workflow tests.

📍 Affects 2 files
  • frontends/ui/src/features/layout/components/ThinkingTab.tsx#L97-L106 (this comment)
  • frontends/ui/src/features/layout/components/ThinkingTab.spec.tsx#L86-L120
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontends/ui/src/features/layout/components/ThinkingTab.tsx` around lines 97
- 106, Update the empty-state branch in ThinkingTab so a non-empty source
collection with no cited items displays “No cited sources yet,” while the
existing research-empty message remains for genuinely source-free states; add a
regression test in ThinkingTab.spec.tsx covering only uncited sources and
selecting Cited (0).

Source: Path instructions

scripts/openshell/check_versions.py (1)

24-24: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

sed -n '1,220p' scripts/openshell/check_versions.py

Repository: NVIDIA-AI-Blueprints/aiq

Length of output: 8704


🏁 Script executed:

python3 - <<'PY'
import re

pat = re.compile(r"\d+\.\d+\.\d+(?:(?:-dev\.|\.dev)\d+(?:\+g[0-9a-fA-F]+)?)?")
samples = [
    "0.0.80",
    "0.0.80rc1",
    "0.0.80.post1",
    "0.0.80+local",
    "0.0.80-dev.1",
    "0.0.80.dev1+gabc1234",
    "v0.0.80rc1",
    "version 0.0.80.post1 build",
]

for s in samples:
    m = pat.search(s)
    print(f"{s!r:28} -> {m.group(0) if m else None!r}")
PY

Repository: NVIDIA-AI-Blueprints/aiq

Length of output: 510


Reject unsupported suffixes in _VERSION_PATTERN. _extract_version() matches prefixes inside 0.0.80rc1, 0.0.80.post1, and 0.0.80+local, which can make unsupported versions look certified. Add a suffix boundary/lookahead and cover rc, post, and local-version cases in tests.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/openshell/check_versions.py` at line 24, Update _VERSION_PATTERN used
by _extract_version() to require a valid suffix boundary after the supported
version formats, preventing matches within rc, post, or local-version strings.
Add tests covering 0.0.80rc1, 0.0.80.post1, and 0.0.80+local, while preserving
matches for the existing supported development and git-suffix forms.
scripts/openshell/setup_openshell.sh (2)

83-83: 📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Derive help examples from the certified version contract.

Hardcoding 0.0.80 duplicates the value already loaded from pyproject.toml and will make the CLI guidance stale on the next certified upgrade.

Proposed fix
-  --openshell-version VERSION   Certified exact OpenShell version only (0.0.80).
+  --openshell-version VERSION   Certified exact OpenShell version only ($DEFAULT_OPENSHELL_VERSION).
...
-  scripts/openshell/setup_openshell.sh --openshell-version 0.0.80 --policy offline
+  scripts/openshell/setup_openshell.sh --openshell-version $DEFAULT_OPENSHELL_VERSION --policy offline

Also applies to: 111-111

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/openshell/setup_openshell.sh` at line 83, Update the help text in
setup_openshell.sh to derive the example version from the certified version
value loaded from pyproject.toml instead of hardcoding 0.0.80. Apply the same
change to both the option description and the corresponding usage example,
preserving the existing certified-version contract.

148-151: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Validate the option value before reading $2.

With set -u, --landlock-compatibility without a value terminates with an unbound-variable error instead of the intended CLI message.

Proposed fix
         --landlock-compatibility)
+            [[ $# -ge 2 ]] || fail "--landlock-compatibility requires a mode"
             LANDLOCK_COMPATIBILITY="$2"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

        --landlock-compatibility)
            [[ $# -ge 2 ]] || fail "--landlock-compatibility requires a mode"
            LANDLOCK_COMPATIBILITY="$2"
            LANDLOCK_COMPATIBILITY_CLI=true
            shift 2
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/openshell/setup_openshell.sh` around lines 148 - 151, Update the
--landlock-compatibility handling in the option-parsing logic to validate that a
value argument exists before reading $2, including under set -u; when missing,
emit the intended CLI error and exit through the existing validation path,
otherwise preserve the current assignment and shift behavior.
scripts/openshell/smoke_openshell_isolation.py (1)

71-73: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Do not inherit best-effort Landlock implicitly.

When the flag is absent, an existing AIQ_OPENSHELL_LIVE_ALLOW_BEST_EFFORT remains in env, allowing strict acceptance to run with weakened isolation.

Proposed fix
     if args.allow_best_effort_landlock:
         env["AIQ_OPENSHELL_LIVE_ALLOW_BEST_EFFORT"] = "1"
+    else:
+        env.pop("AIQ_OPENSHELL_LIVE_ALLOW_BEST_EFFORT", None)
     return env
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

    if args.allow_best_effort_landlock:
        env["AIQ_OPENSHELL_LIVE_ALLOW_BEST_EFFORT"] = "1"
    else:
        env.pop("AIQ_OPENSHELL_LIVE_ALLOW_BEST_EFFORT", None)
    return env
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/openshell/smoke_openshell_isolation.py` around lines 71 - 73, Update
the environment construction logic around the allow_best_effort_landlock flag so
AIQ_OPENSHELL_LIVE_ALLOW_BEST_EFFORT is removed from env when the flag is
absent, and set to "1" only when the flag is enabled. Preserve the existing
return env behavior.
scripts/openshell/version_contract.py (1)

24-27: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '--- scripts/openshell/version_contract.py (outline) ---'
ast-grep outline scripts/openshell/version_contract.py --view expanded || true

echo
echo '--- scripts/openshell/version_contract.py (selected lines) ---'
nl -ba scripts/openshell/version_contract.py | sed -n '1,140p'

echo
echo '--- adapter_version usages ---'
rg -n "adapter_version" -S .

Repository: NVIDIA-AI-Blueprints/aiq

Length of output: 807


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '--- scripts/openshell/version_contract.py ---'
awk '{printf "%4d  %s\n", NR, $0}' scripts/openshell/version_contract.py | sed -n '1,140p'

echo
echo '--- adapter_version usages ---'
rg -n "adapter_version" scripts . || true

Repository: NVIDIA-AI-Blueprints/aiq

Length of output: 5652


Make adapter_version required in the contract.

load_contract() rejects missing or non-string adapter-version values and always returns a string, so OpenShellContract.adapter_version should be str rather than str | None. If missing values are intended, the loader and extra-version comparison need to handle None explicitly.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/openshell/version_contract.py` around lines 24 - 27, Update
OpenShellContract.adapter_version to the required str type, matching
load_contract()’s validation and string return contract; do not add optional
handling unless the loader and extra-version comparison are explicitly changed
to support None.
sources/knowledge_layer/src/azure_ai_search/adapter.py (4)

761-762: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Validate metadata is a mapping before unpacking it.

json.dumps() accepts lists and strings, but the later {**file_metadata, ...} requires a mapping. Invalid metadata therefore crashes submit_job() before a failed job can be recorded. Reject non-dict metadata explicitly.

Also applies to: 789-792

🧰 Tools
🪛 ast-grep (0.44.1)

[info] 761-761: use jsonify instead of json.dumps for JSON output
Context: json.dumps(file_metadata, separators=(",", ":"), sort_keys=True)
Note: [CWE-116] Improper Encoding or Escaping of Output.

(use-jsonify)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@sources/knowledge_layer/src/azure_ai_search/adapter.py` around lines 761 -
762, Validate job_config metadata in submit_job before json.dumps() and before
any {**file_metadata, ...} expansion, requiring a dict/mapping and rejecting
other values explicitly. Preserve the existing empty-metadata default, and
ensure invalid metadata follows the failed-job recording path instead of raising
during submission.

1127-1131: 🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== adapter.py around target lines ==\n'
sed -n '1080,1160p' sources/knowledge_layer/src/azure_ai_search/adapter.py

printf '\n== search for _write_file_manifest and delete_collection ==\n'
rg -n "_write_file_manifest|delete_collection|_get_collection_manifest|_COLLECTION_ACTIVE|register_summary" sources/knowledge_layer/src/azure_ai_search/adapter.py

printf '\n== surrounding definitions ==\n'
python3 - <<'PY'
from pathlib import Path
path = Path('sources/knowledge_layer/src/azure_ai_search/adapter.py')
text = path.read_text()
for needle in ['def _write_file_manifest', 'def delete_collection', 'def _get_collection_manifest', 'class', 'async def delete_collection']:
    idx = text.find(needle)
    if idx != -1:
        start = text.rfind('\n', 0, idx)
        print(f"\n--- {needle} ---")
        print(text[max(0, start-400): idx+1200])
PY

Repository: NVIDIA-AI-Blueprints/aiq

Length of output: 12725


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== delete_collection continuation ==\n'
sed -n '1167,1245p' sources/knowledge_layer/src/azure_ai_search/adapter.py

printf '\n== _write_document implementation ==\n'
rg -n "def _write_document|def _delete_document|_deleted_files|_jobs_lock" sources/knowledge_layer/src/azure_ai_search/adapter.py
sed -n '520,760p' sources/knowledge_layer/src/azure_ai_search/adapter.py

printf '\n== file lifecycle helpers around deletion/writes ==\n'
sed -n '760,910p' sources/knowledge_layer/src/azure_ai_search/adapter.py

Repository: NVIDIA-AI-Blueprints/aiq

Length of output: 22316


Prevent file-manifest writes after deletion begins. _update_file_progress() checks the collection once, then writes the file manifest later; a concurrent delete_collection() can still remove the collection and its files in that gap, recreating an orphaned record. Recheck the collection state right before _write_file_manifest(), or gate progress writes on a deletion/deleted flag.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@sources/knowledge_layer/src/azure_ai_search/adapter.py` around lines 1127 -
1131, Update _update_file_progress so it revalidates the collection’s active
state immediately before calling _write_file_manifest, preventing a concurrent
delete_collection from allowing the manifest write. Preserve summary
registration only when the manifest write remains valid, and use the existing
collection status/deletion state symbols.

1231-1249: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Handle a file disappearing between the two existence checks.

If the file is removed after upload_file() checks is_file() but before submit_job() validates it, the failed job has no file_details; indexing [0] then raises IndexError. Return a failed FileInfo when no detail exists, or make submit_job() create an explicit failed detail.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@sources/knowledge_layer/src/azure_ai_search/adapter.py` around lines 1231 -
1249, Update upload_file around submit_job and the subsequent
_jobs[job_id].file_details access to handle a job with no file details when the
file disappears between validation checks. Return a failed FileInfo with the
file path, collection, and clear error message when file_details is empty, while
preserving the existing detail-copy path when a detail is available.

1258-1283: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE='sources/knowledge_layer/src/azure_ai_search/adapter.py'

echo '--- outline ---'
ast-grep outline "$FILE" --view expanded | sed -n '1,220p'

echo
echo '--- relevant ranges ---'
sed -n '1120,1315p' "$FILE" | cat -n

echo
echo '--- wait/search helpers ---'
rg -n "_wait_for_search_state|_delete_document_ids|_iter_documents|_delete_file_documents|_get_validated_search_client|_record_filter|_RECORD_FILE|_RECORD_COLLECTION" "$FILE"

Repository: NVIDIA-AI-Blueprints/aiq

Length of output: 19801


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE='sources/knowledge_layer/src/azure_ai_search/adapter.py'

python3 - <<'PY'
from pathlib import Path
path = Path('sources/knowledge_layer/src/azure_ai_search/adapter.py')
text = path.read_text()
for needle in ['def _wait_for_search_state', 'def _delete_document_ids', 'def _delete_file_documents', 'def delete_collection', 'def delete_file', 'def _iter_documents']:
    idx = text.find(needle)
    if idx != -1:
        start = text.rfind('\n', 0, idx) + 1
        end = text.find('\nclass ', idx)
        if end == -1:
            end = len(text)
        print(f'\n### {needle}\n')
        print(text[start:end][:5000])
PY

Repository: NVIDIA-AI-Blueprints/aiq

Length of output: 29262


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE='sources/knowledge_layer/src/azure_ai_search/adapter.py'

python3 - <<'PY'
from pathlib import Path

path = Path('sources/knowledge_layer/src/azure_ai_search/adapter.py')
lines = path.read_text().splitlines()

targets = [
    'def _wait_for_search_state',
    'def _delete_document_ids',
    'def _delete_file_documents',
    'def delete_collection',
    'def delete_file',
    'def _iter_documents',
]
for target in targets:
    for i, line in enumerate(lines):
        if line.startswith(target):
            start = max(0, i - 10)
            end = min(len(lines), i + 120)
            print(f"\n### {target} @ line {i+1}\n")
            for j in range(start, end):
                print(f"{j+1:5d}: {lines[j]}")
            break
    else:
        print(f"\n### {target} not found\n")
PY

Repository: NVIDIA-AI-Blueprints/aiq

Length of output: 395


Wait for all deleted Azure Search records to disappear before returning.

  • sources/knowledge_layer/src/azure_ai_search/adapter.py#L1182-L1201: delete_collection issues deletes but never waits for the collection content to become absent.
  • sources/knowledge_layer/src/azure_ai_search/adapter.py#L1258-L1283: delete_file waits only on the file manifest; include the chunk records in the post-delete check too.
📍 Affects 1 file
  • sources/knowledge_layer/src/azure_ai_search/adapter.py#L1258-L1283 (this comment)
  • sources/knowledge_layer/src/azure_ai_search/adapter.py#L1182-L1201
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@sources/knowledge_layer/src/azure_ai_search/adapter.py` around lines 1258 -
1283, Update delete_file and delete_collection in
sources/knowledge_layer/src/azure_ai_search/adapter.py at lines 1258-1283 and
1182-1201 so they wait for all deleted Azure Search records to disappear before
returning. In delete_file, extend the post-delete _wait_for_search_state check
beyond the file manifest to include its chunk records; in delete_collection, add
an equivalent absence wait for the collection’s content after issuing deletions.
src/aiq_agent/agents/deep_researcher/register.py (1)

298-306: 🩺 Stability & Availability | 🟠 Major | 🏗️ Heavy lift

Sandbox finalization remains unbounded despite using to_thread().

Both terminal paths await synchronous provider cleanup indefinitely; moving it to a thread protects the event loop, not request or worker completion.

  • src/aiq_agent/agents/deep_researcher/register.py#L298-L306: bound request-scoped finalization so cancellation always completes.
  • frontends/aiq_api/src/aiq_api/jobs/runner.py#L886-L893: bound terminal cleanup so a Dask task cannot remain occupied indefinitely.

Prefer provider-level deadlines, with a call-site timeout as containment.

As per path instructions, preserve agent “async cancellation” and API “async job lifecycle” behavior.

📍 Affects 2 files
  • src/aiq_agent/agents/deep_researcher/register.py#L298-L306 (this comment)
  • frontends/aiq_api/src/aiq_api/jobs/runner.py#L886-L893
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/aiq_agent/agents/deep_researcher/register.py` around lines 298 - 306, The
synchronous provider cleanup in the deep-researcher finalization path and the
API job terminal cleanup remain unbounded. Add provider-level deadlines and
call-site timeouts around the `active_agent.finalize` flow in `register.py` and
the corresponding terminal cleanup in `runner.py`; preserve agent async
cancellation semantics and the API async job lifecycle while ensuring both
request/task completions cannot wait indefinitely.

Source: Path instructions

tests/aiq_agent/jobs/test_runner.py (2)

888-891: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Do not persist raw backend exception messages.

This expectation codifies exposing str(error) through externally visible job status. Database exceptions can contain queries, hosts, identifiers, or credentials; retain a stable sanitized message and log the detailed exception only through secret-safe server logging.

Proposed expectation
-            error="transient database failure",
+            error="failed to persist encrypted job events",

As per coding guidelines, “Never print or log secret values, including in tool output or error messages.” As per path instructions, treat job-runner changes as “externally visible contracts” and check “error responses.”

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

        mock_job_store.update_status.assert_awaited_with(
            "job-1",
            JobStatus.FAILURE,
            error="failed to persist encrypted job events",
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/aiq_agent/jobs/test_runner.py` around lines 888 - 891, Update the
job-runner failure handling that calls mock_job_store.update_status with
JobStatus.FAILURE so externally persisted errors use a stable sanitized message
instead of str(error). Keep detailed exception information restricted to
secret-safe server logging, and adjust the expectation around update_status
accordingly.

Sources: Coding guidelines, Path instructions


1189-1200: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Restore coverage for workflow configs without the async flag.

_get_worker_function_type directly reads config.workflow.use_async_deep_research; removing the missing-attribute case permits an AttributeError for legacy or alternate workflow configurations. Retain that test and default the absent flag to False, for example with getattr.

As per path instructions, job-runner changes require tests for “job state transitions.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/aiq_agent/jobs/test_runner.py` around lines 1189 - 1200, Update
_get_worker_function_type to safely treat a missing
workflow.use_async_deep_research attribute as False, while preserving the
existing enabled and disabled behavior. Restore coverage using a workflow
configuration without the async flag and add the required job state transition
tests for the job-runner change.

Source: Path instructions

Manushpm8 and others added 5 commits July 16, 2026 22:18
Brings the chat UI to the premium layout: a live phased "thinking" trace
(status dots, durations, tool-call rows, a "using" source chip), answers with
superscript citations and a styled source list, an interactive clarifier, a
restyled composer with a stop control, a collapsible sessions rail, and
push-style data-source and research panels.

- chat: ChatThinking (phased live trace), AgentResponse (citations + sources +
  copy + answer reveal), AgentPrompt (interactive clarifier with plan approval),
  UserMessage and banner polish.
- layout: MainLayout push panels, ChatArea turn grouping + run lane + pinned
  autoscroll, AppBar theme toggle + active data-sources state, InputArea composer
  restyle + stop, SessionsPanel collapsible rail, DataSourcesPanel push re-skin,
  and the research-panel tabs and cards.
- app: mount the reduced-motion Motion provider at the root.

Per-user OAuth, human-in-the-loop navigation blocking, and rich artifact/file
handling are preserved. The model picker is omitted (prod exposes no selectable
models). No predictive/analytical/warehouse UI is ported. Full suite green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Manush Maheshwari <manushm@nvidia.com>
- AgentPrompt: do not show "Plan approved" when a responded prompt has no
  response (neutral state).
- AgentResponse: surface report-load failures inline with role="alert" and a
  Retry button instead of only a title tooltip.
- AgentCard: keep distinct tool calls with unrecognized inputs separate, and
  let a terminal state replace a stale running row.
- AgentsTab: count rendered groups (agents plus orphan tool calls), not just
  the agent list.
- ReportTab: bound the expanded generated-files list with a scroll area.
- SessionsPanel: return focus to the search trigger when the search closes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Manush Maheshwari <manushm@nvidia.com>
The re-skin dropped aiq-rfm's custom surface/text/border palette and the base
NVIDIA Sans font-family, so surfaces fell back to KUI defaults. Restore the
light and dark token overrides and the html/body font-family + smoothing so
the theme matches aiq-rfm.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Manush Maheshwari <manushm@nvidia.com>
There is no model selector in the composer, so drop the model favicon + name
badge from the response summary bar (and the local favicon helper). The model
data field is left in place, only the display is removed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Manush Maheshwari <manushm@nvidia.com>
Signed-off-by: Manush Mohan <manushm@nvidia.com>
@Manushpm8
Manushpm8 force-pushed the feat/ui-chat-look branch from 860114e to 4305114 Compare July 16, 2026 16:48

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 17

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
frontends/ui/src/features/layout/components/MainLayout.tsx (1)

169-198: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Centralize the new-session guard across bootstrap and active interactions.

New-session safety is currently caller-local, leaving two unguarded paths:

  • frontends/ui/src/features/layout/components/MainLayout.tsx#L169-L198: include bootstrap/user hydration in a shared disabled state and guard handleNewSession.
  • frontends/ui/src/features/layout/components/SessionsPanel.tsx#L418-L424: disable the empty-state CTA using that same guard.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontends/ui/src/features/layout/components/MainLayout.tsx` around lines 169
- 198, The new-session guard must cover bootstrap and user-hydration state
across all entry points. In
frontends/ui/src/features/layout/components/MainLayout.tsx lines 169-198,
include those states in the shared disabled condition and guard
handleNewSession; in
frontends/ui/src/features/layout/components/SessionsPanel.tsx lines 418-424,
reuse that same guard to disable the empty-state CTA.

Source: Path instructions

♻️ Duplicate comments (2)
frontends/ui/src/features/layout/components/AgentCard.tsx (1)

70-75: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Do not deduplicate by a truncated display label.

getToolArgSummary truncates values, so distinct long arguments with the same prefix collapse into one row. Build the key from full canonical input while retaining the summary only for display, and add a collision regression test.

As per path instructions, preserve report/chat state consistency and require tests for changed workflows.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontends/ui/src/features/layout/components/AgentCard.tsx` around lines 70 -
75, Update dedupeToolCalls so its Map key uses the full canonicalized tc.input
together with tc.name (and an appropriate fallback for unavailable input),
rather than the truncated getToolArgSummary result; keep the summary solely for
display. Add a regression test covering distinct long inputs sharing the same
truncated prefix, and verify report/chat state remains consistent across the
affected workflows.

Source: Path instructions

frontends/ui/src/features/layout/components/AgentsTab.tsx (1)

46-51: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Derive header state from the same visible phases that ChatThinking renders.

These counts include internal steps such as <workflow>, while ChatThinking filters them. A wrapper-only run can therefore show a count or “running” badge beside an empty trace. Share the visibility/phase derivation and add wrapper-only coverage.

As per path instructions, review UI changes for “report/chat state consistency.”

Also applies to: 79-92

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontends/ui/src/features/layout/components/AgentsTab.tsx` around lines 46 -
51, Update AgentsTab’s isEmpty, runningCount, and renderedGroupCount to use the
same visible-phase filtering and derivation as ChatThinking, excluding internal
wrapper steps such as <workflow>. Share or reuse that visibility logic rather
than maintaining separate filters, and add coverage for a wrapper-only run so
the header shows no count or running badge beside an empty trace.

Source: Path instructions

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@frontends/ui/src/app/globals.css`:
- Line 88: Update the --text-color-subtle definitions, including the theme and
raised-surface variants, to use contrast-validated light and dark values meeting
at least 4.5:1 against their respective base surfaces; preserve the existing
token usage by .mono-label.
- Line 130: Update the text-rendering value in the global stylesheet to
lowercase `optimizelegibility` to satisfy the configured Stylelint
value-keyword-case rule, then run the UI lint, type-check, tests, and build
validation.

In `@frontends/ui/src/features/chat/components/AgentPrompt.tsx`:
- Around line 143-154: Update AgentPrompt to retain and prioritize the incoming
type prop when determining approval prompts: treat type="approval" as approval
regardless of content, while preserving APPROVAL_PROMPT_RE as a legacy fallback
for prompts without that type. Add a test covering type="approval" with
non-matching content and verify the approval controls render.
- Around line 200-219: Update the keydown logic in AgentPrompt’s
useEffect/onKeyDown flow to detect when focus is on an interactive control and
return without handling Enter, preserving native activation of the focused
Reject button. Ensure keyboard approval still works when focus is not on a
control, and add a regression test that tabs to Reject and presses Enter,
verifying rejection rather than approval.

In `@frontends/ui/src/features/chat/components/AgentResponse.tsx`:
- Around line 93-94: Update the historical report action in AgentResponse, using
isAnotherJobStreaming, so a completed job’s “View Report” cannot route to
another currently streaming job; disable the action or make the alternate
behavior explicit while preserving the normal path when no other job is
streaming. Add or update tests covering this user-visible branch and report/chat
state consistency.

In `@frontends/ui/src/features/chat/components/ChatThinking.tsx`:
- Around line 672-679: Update phaseEnd in ChatThinking so the fallback for
phases with children uses the final child’s completion timestamp rather than its
start timestamp. Preserve the existing precedence for head.completedAt,
subsequent phases, active thinking, and stoppedAt, and retain the start-time
fallback when no children exist.
- Around line 604-609: Update the realSteps useMemo to also filter out
reflection nodes, using the existing reflection-identification helper or
predicate, so reflection-only streams produce an empty realSteps result and
follow the existing empty-state path. Preserve the current reasoning and
explanation exclusions.
- Around line 179-197: The filtering in the enriched steps flow incorrectly
removes nested calls based only on the tool label. Update the logic around
topLevelLabels and enriched so calls use a stable call ID when available;
otherwise retain nested rows unless both their label and original input summary
match the top-level call. Add a regression test covering top-level and nested
web_search_tool calls with different inputs.

In `@frontends/ui/src/features/chat/lib/session-activity.ts`:
- Around line 22-43: The lastUserMessageTime function currently recognizes user
messages only through messageType, so messages with role: 'user' and an
undefined messageType are ignored. Update its user-message classification to
match ChatArea’s fallback behavior, treating role-only user messages as user
messages while preserving explicit non-user messageType handling and the
existing recency sorting flow.

In `@frontends/ui/src/features/layout/components/AgentCard.tsx`:
- Around line 102-108: Update the disclosure button in AgentCard so
aria-expanded and aria-controls are only rendered when canExpand is true;
otherwise omit both attributes while preserving the disabled behavior and
existing values for agents with controlled content.
- Around line 90-94: Update AgentCard’s expandability and rendering logic to
preserve the public AgentInfo.output contract: a completed agent with only
output must remain enabled and display its result. Include output alongside tool
calls/currentTask where determining expandable content and rendering the card,
while preserving report/chat state consistency. Add coverage for the output-only
completed-agent workflow.

In `@frontends/ui/src/features/layout/components/AgentsTab.tsx`:
- Around line 53-59: Update the scroll logic in the useEffect associated with
scrollRef to reuse the shared isPinnedToBottom predicate instead of calculating
nearBottom locally. Preserve the existing auto-scroll behavior and the
predicate’s inclusive <=120px boundary.

In `@frontends/ui/src/features/layout/components/DataConnectionsTab.tsx`:
- Around line 43-57: Update the displaySources mapping in DataConnectionsTab to
preserve each source’s per-user OAuth metadata using the same mapping as
DataSourcesPanel, including the perUserAuth field consumed by
DataConnectionCard. Ensure disconnected protected sources render
Connect/Reconnect and cannot be selected before OAuth completes, and add a
regression test covering that state.

In `@frontends/ui/src/features/layout/components/DataSourcesPanel.tsx`:
- Around line 220-246: Update the panel controlled by the existing isOpen state
in DataSourcesPanel so closing it immediately disables descendant interaction
while the width/opacity transition continues, using the appropriate inert
behavior alongside aria-hidden. Track the opener element and restore focus to it
when the panel closes, while preserving normal focusability and focus behavior
when the panel is open.
- Around line 316-365: Update the “Disable / Enable All” control around the
outer Flex and Switch so the Switch is the sole interactive control: remove the
outer role="button", tabIndex, click and keyboard handlers, button-specific ARIA
attributes, and event-stopping wrapper. Preserve the existing label, checked
state, busy-state disabling, and handleToggleAll behavior through the Switch.
- Around line 388-395: Update the Retry Button’s onClick handler to call
fetchDataSources with the existing idToken, matching the authenticated refresh
path. Preserve the current retry behavior while ensuring authenticated
deployments reuse the token.

In `@frontends/ui/src/features/layout/components/ThinkingTab.tsx`:
- Around line 82-105: Update the empty-state branch in ThinkingTab so the cited
filter with no results does not display the generic “Sources the agent reads
will appear here” message; either hide/disable the cited filter when
cited.length is zero or render a filter-specific “No sources were cited in the
report” state. Preserve the existing empty state when no sources exist, and add
or update the spec to cover the cited-empty workflow along with resilient
loading and error states.

---

Outside diff comments:
In `@frontends/ui/src/features/layout/components/MainLayout.tsx`:
- Around line 169-198: The new-session guard must cover bootstrap and
user-hydration state across all entry points. In
frontends/ui/src/features/layout/components/MainLayout.tsx lines 169-198,
include those states in the shared disabled condition and guard
handleNewSession; in
frontends/ui/src/features/layout/components/SessionsPanel.tsx lines 418-424,
reuse that same guard to disable the empty-state CTA.

---

Duplicate comments:
In `@frontends/ui/src/features/layout/components/AgentCard.tsx`:
- Around line 70-75: Update dedupeToolCalls so its Map key uses the full
canonicalized tc.input together with tc.name (and an appropriate fallback for
unavailable input), rather than the truncated getToolArgSummary result; keep the
summary solely for display. Add a regression test covering distinct long inputs
sharing the same truncated prefix, and verify report/chat state remains
consistent across the affected workflows.

In `@frontends/ui/src/features/layout/components/AgentsTab.tsx`:
- Around line 46-51: Update AgentsTab’s isEmpty, runningCount, and
renderedGroupCount to use the same visible-phase filtering and derivation as
ChatThinking, excluding internal wrapper steps such as <workflow>. Share or
reuse that visibility logic rather than maintaining separate filters, and add
coverage for a wrapper-only run so the header shows no count or running badge
beside an empty trace.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Enterprise

Run ID: e3b52cb2-55e1-4df3-9a89-c3e28b70c137

📥 Commits

Reviewing files that changed from the base of the PR and between 6d43fc5 and 4305114.

📒 Files selected for processing (65)
  • frontends/ui/src/app/globals.css
  • frontends/ui/src/app/page.tsx
  • frontends/ui/src/app/providers.tsx
  • frontends/ui/src/features/chat/components/AgentPrompt.spec.tsx
  • frontends/ui/src/features/chat/components/AgentPrompt.tsx
  • frontends/ui/src/features/chat/components/AgentResponse.spec.tsx
  • frontends/ui/src/features/chat/components/AgentResponse.tsx
  • frontends/ui/src/features/chat/components/ChatThinking.spec.tsx
  • frontends/ui/src/features/chat/components/ChatThinking.tsx
  • frontends/ui/src/features/chat/components/DeepResearchBanner.tsx
  • frontends/ui/src/features/chat/components/ErrorBanner.tsx
  • frontends/ui/src/features/chat/components/FileUploadBanner.tsx
  • frontends/ui/src/features/chat/components/NoSourcesBanner.tsx
  • frontends/ui/src/features/chat/components/UserMessage.tsx
  • frontends/ui/src/features/chat/components/index.ts
  • frontends/ui/src/features/chat/lib/session-activity.ts
  • frontends/ui/src/features/layout/components/AgentCard.spec.tsx
  • frontends/ui/src/features/layout/components/AgentCard.tsx
  • frontends/ui/src/features/layout/components/AgentsTab.spec.tsx
  • frontends/ui/src/features/layout/components/AgentsTab.tsx
  • frontends/ui/src/features/layout/components/AppBar.spec.tsx
  • frontends/ui/src/features/layout/components/AppBar.tsx
  • frontends/ui/src/features/layout/components/ChatArea.autoscroll.spec.tsx
  • frontends/ui/src/features/layout/components/ChatArea.spec.tsx
  • frontends/ui/src/features/layout/components/ChatArea.tsx
  • frontends/ui/src/features/layout/components/CitationCard.spec.tsx
  • frontends/ui/src/features/layout/components/CitationCard.tsx
  • frontends/ui/src/features/layout/components/DataConnectionCard.tsx
  • frontends/ui/src/features/layout/components/DataConnectionsTab.spec.tsx
  • frontends/ui/src/features/layout/components/DataConnectionsTab.tsx
  • frontends/ui/src/features/layout/components/DataSourcesPanel.spec.tsx
  • frontends/ui/src/features/layout/components/DataSourcesPanel.tsx
  • frontends/ui/src/features/layout/components/FileCard.tsx
  • frontends/ui/src/features/layout/components/FileSourceCard.spec.tsx
  • frontends/ui/src/features/layout/components/FileSourceCard.tsx
  • frontends/ui/src/features/layout/components/FileSourcesTab.spec.tsx
  • frontends/ui/src/features/layout/components/FileSourcesTab.tsx
  • frontends/ui/src/features/layout/components/InputArea.tsx
  • frontends/ui/src/features/layout/components/MainLayout.spec.tsx
  • frontends/ui/src/features/layout/components/MainLayout.tsx
  • frontends/ui/src/features/layout/components/ReportCard.spec.tsx
  • frontends/ui/src/features/layout/components/ReportCard.tsx
  • frontends/ui/src/features/layout/components/ReportTab.spec.tsx
  • frontends/ui/src/features/layout/components/ReportTab.tsx
  • frontends/ui/src/features/layout/components/ResearchPanel.spec.tsx
  • frontends/ui/src/features/layout/components/ResearchPanel.tsx
  • frontends/ui/src/features/layout/components/SessionsPanel.spec.tsx
  • frontends/ui/src/features/layout/components/SessionsPanel.tsx
  • frontends/ui/src/features/layout/components/SettingsPanel.spec.tsx
  • frontends/ui/src/features/layout/components/SettingsPanel.tsx
  • frontends/ui/src/features/layout/components/SourceCard.spec.tsx
  • frontends/ui/src/features/layout/components/SourceCard.tsx
  • frontends/ui/src/features/layout/components/TaskCard.spec.tsx
  • frontends/ui/src/features/layout/components/TaskCard.tsx
  • frontends/ui/src/features/layout/components/TasksTab.spec.tsx
  • frontends/ui/src/features/layout/components/TasksTab.tsx
  • frontends/ui/src/features/layout/components/ThinkingTab.spec.tsx
  • frontends/ui/src/features/layout/components/ThinkingTab.tsx
  • frontends/ui/src/features/layout/components/ThoughtCard.spec.tsx
  • frontends/ui/src/features/layout/components/ThoughtCard.tsx
  • frontends/ui/src/features/layout/components/index.ts
  • frontends/ui/src/features/layout/index.ts
  • frontends/ui/src/features/layout/store.spec.ts
  • frontends/ui/src/shared/lib/scroll.spec.ts
  • frontends/ui/src/shared/lib/scroll.ts
💤 Files with no reviewable changes (14)
  • frontends/ui/src/features/chat/components/NoSourcesBanner.tsx
  • frontends/ui/src/features/chat/components/ErrorBanner.tsx
  • frontends/ui/src/features/layout/components/SourceCard.spec.tsx
  • frontends/ui/src/features/layout/components/TasksTab.spec.tsx
  • frontends/ui/src/features/chat/components/FileUploadBanner.tsx
  • frontends/ui/src/features/layout/components/CitationCard.spec.tsx
  • frontends/ui/src/features/layout/components/DataConnectionsTab.spec.tsx
  • frontends/ui/src/features/layout/components/ResearchPanel.spec.tsx
  • frontends/ui/src/features/chat/components/DeepResearchBanner.tsx
  • frontends/ui/src/features/layout/components/FileSourcesTab.spec.tsx
  • frontends/ui/src/features/chat/components/index.ts
  • frontends/ui/src/features/layout/components/ReportCard.spec.tsx
  • frontends/ui/src/features/layout/components/index.ts
  • frontends/ui/src/features/layout/components/SettingsPanel.spec.tsx
📜 Review details
🧰 Additional context used
📓 Path-based instructions (3)
frontends/ui/**/*.{js,ts,jsx,tsx,vue}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Run npm lint, type-check, and build validation for UI changes in frontends/ui

Files:

  • frontends/ui/src/features/layout/components/SettingsPanel.tsx
  • frontends/ui/src/features/layout/components/ChatArea.autoscroll.spec.tsx
  • frontends/ui/src/shared/lib/scroll.ts
  • frontends/ui/src/app/page.tsx
  • frontends/ui/src/features/layout/components/TaskCard.spec.tsx
  • frontends/ui/src/shared/lib/scroll.spec.ts
  • frontends/ui/src/features/layout/components/DataSourcesPanel.spec.tsx
  • frontends/ui/src/features/layout/components/SourceCard.tsx
  • frontends/ui/src/features/layout/index.ts
  • frontends/ui/src/features/layout/store.spec.ts
  • frontends/ui/src/app/providers.tsx
  • frontends/ui/src/features/layout/components/CitationCard.tsx
  • frontends/ui/src/features/chat/components/UserMessage.tsx
  • frontends/ui/src/features/layout/components/FileCard.tsx
  • frontends/ui/src/features/layout/components/AgentsTab.tsx
  • frontends/ui/src/features/chat/lib/session-activity.ts
  • frontends/ui/src/features/layout/components/DataConnectionCard.tsx
  • frontends/ui/src/features/layout/components/TaskCard.tsx
  • frontends/ui/src/features/layout/components/ThinkingTab.tsx
  • frontends/ui/src/features/layout/components/TasksTab.tsx
  • frontends/ui/src/features/layout/components/ThoughtCard.tsx
  • frontends/ui/src/features/chat/components/AgentResponse.tsx
  • frontends/ui/src/features/layout/components/ReportTab.tsx
  • frontends/ui/src/features/layout/components/AgentsTab.spec.tsx
  • frontends/ui/src/features/layout/components/ReportCard.tsx
  • frontends/ui/src/features/chat/components/AgentPrompt.spec.tsx
  • frontends/ui/src/features/layout/components/ThoughtCard.spec.tsx
  • frontends/ui/src/features/layout/components/InputArea.tsx
  • frontends/ui/src/features/layout/components/ReportTab.spec.tsx
  • frontends/ui/src/features/layout/components/AgentCard.spec.tsx
  • frontends/ui/src/features/layout/components/AgentCard.tsx
  • frontends/ui/src/features/layout/components/DataSourcesPanel.tsx
  • frontends/ui/src/features/chat/components/ChatThinking.spec.tsx
  • frontends/ui/src/features/layout/components/DataConnectionsTab.tsx
  • frontends/ui/src/features/layout/components/FileSourcesTab.tsx
  • frontends/ui/src/features/layout/components/MainLayout.spec.tsx
  • frontends/ui/src/features/chat/components/AgentPrompt.tsx
  • frontends/ui/src/features/chat/components/AgentResponse.spec.tsx
  • frontends/ui/src/features/layout/components/ThinkingTab.spec.tsx
  • frontends/ui/src/features/layout/components/MainLayout.tsx
  • frontends/ui/src/features/layout/components/FileSourceCard.tsx
  • frontends/ui/src/features/layout/components/FileSourceCard.spec.tsx
  • frontends/ui/src/features/chat/components/ChatThinking.tsx
  • frontends/ui/src/features/layout/components/ChatArea.spec.tsx
  • frontends/ui/src/features/layout/components/ResearchPanel.tsx
  • frontends/ui/src/features/layout/components/ChatArea.tsx
  • frontends/ui/src/features/layout/components/AppBar.spec.tsx
  • frontends/ui/src/features/layout/components/SessionsPanel.tsx
  • frontends/ui/src/features/layout/components/SessionsPanel.spec.tsx
  • frontends/ui/src/features/layout/components/AppBar.tsx
frontends/ui/**/*.{ts,tsx,jsx,js}

📄 CodeRabbit inference engine (AGENTS.md)

frontends/ui/**/*.{ts,tsx,jsx,js}: The UI is built with Next.js / React / TypeScript / Tailwind with KUI components; reuse existing KUI components and visual patterns rather than introducing new ones
Validate UI-affecting changes with npm run lint, npm run type-check, and npm run test:ci, and include a screenshot for visible changes

Files:

  • frontends/ui/src/features/layout/components/SettingsPanel.tsx
  • frontends/ui/src/features/layout/components/ChatArea.autoscroll.spec.tsx
  • frontends/ui/src/shared/lib/scroll.ts
  • frontends/ui/src/app/page.tsx
  • frontends/ui/src/features/layout/components/TaskCard.spec.tsx
  • frontends/ui/src/shared/lib/scroll.spec.ts
  • frontends/ui/src/features/layout/components/DataSourcesPanel.spec.tsx
  • frontends/ui/src/features/layout/components/SourceCard.tsx
  • frontends/ui/src/features/layout/index.ts
  • frontends/ui/src/features/layout/store.spec.ts
  • frontends/ui/src/app/providers.tsx
  • frontends/ui/src/features/layout/components/CitationCard.tsx
  • frontends/ui/src/features/chat/components/UserMessage.tsx
  • frontends/ui/src/features/layout/components/FileCard.tsx
  • frontends/ui/src/features/layout/components/AgentsTab.tsx
  • frontends/ui/src/features/chat/lib/session-activity.ts
  • frontends/ui/src/features/layout/components/DataConnectionCard.tsx
  • frontends/ui/src/features/layout/components/TaskCard.tsx
  • frontends/ui/src/features/layout/components/ThinkingTab.tsx
  • frontends/ui/src/features/layout/components/TasksTab.tsx
  • frontends/ui/src/features/layout/components/ThoughtCard.tsx
  • frontends/ui/src/features/chat/components/AgentResponse.tsx
  • frontends/ui/src/features/layout/components/ReportTab.tsx
  • frontends/ui/src/features/layout/components/AgentsTab.spec.tsx
  • frontends/ui/src/features/layout/components/ReportCard.tsx
  • frontends/ui/src/features/chat/components/AgentPrompt.spec.tsx
  • frontends/ui/src/features/layout/components/ThoughtCard.spec.tsx
  • frontends/ui/src/features/layout/components/InputArea.tsx
  • frontends/ui/src/features/layout/components/ReportTab.spec.tsx
  • frontends/ui/src/features/layout/components/AgentCard.spec.tsx
  • frontends/ui/src/features/layout/components/AgentCard.tsx
  • frontends/ui/src/features/layout/components/DataSourcesPanel.tsx
  • frontends/ui/src/features/chat/components/ChatThinking.spec.tsx
  • frontends/ui/src/features/layout/components/DataConnectionsTab.tsx
  • frontends/ui/src/features/layout/components/FileSourcesTab.tsx
  • frontends/ui/src/features/layout/components/MainLayout.spec.tsx
  • frontends/ui/src/features/chat/components/AgentPrompt.tsx
  • frontends/ui/src/features/chat/components/AgentResponse.spec.tsx
  • frontends/ui/src/features/layout/components/ThinkingTab.spec.tsx
  • frontends/ui/src/features/layout/components/MainLayout.tsx
  • frontends/ui/src/features/layout/components/FileSourceCard.tsx
  • frontends/ui/src/features/layout/components/FileSourceCard.spec.tsx
  • frontends/ui/src/features/chat/components/ChatThinking.tsx
  • frontends/ui/src/features/layout/components/ChatArea.spec.tsx
  • frontends/ui/src/features/layout/components/ResearchPanel.tsx
  • frontends/ui/src/features/layout/components/ChatArea.tsx
  • frontends/ui/src/features/layout/components/AppBar.spec.tsx
  • frontends/ui/src/features/layout/components/SessionsPanel.tsx
  • frontends/ui/src/features/layout/components/SessionsPanel.spec.tsx
  • frontends/ui/src/features/layout/components/AppBar.tsx
frontends/ui/**/*

⚙️ CodeRabbit configuration file

frontends/ui/**/*: Review UI changes for strict TypeScript behavior, API contract alignment, auth/session handling, accessible controls,
resilient loading and error states, and report/chat state consistency. Prefer existing UI patterns and require tests
for changed user-visible workflows.

Files:

  • frontends/ui/src/features/layout/components/SettingsPanel.tsx
  • frontends/ui/src/features/layout/components/ChatArea.autoscroll.spec.tsx
  • frontends/ui/src/shared/lib/scroll.ts
  • frontends/ui/src/app/page.tsx
  • frontends/ui/src/features/layout/components/TaskCard.spec.tsx
  • frontends/ui/src/shared/lib/scroll.spec.ts
  • frontends/ui/src/features/layout/components/DataSourcesPanel.spec.tsx
  • frontends/ui/src/features/layout/components/SourceCard.tsx
  • frontends/ui/src/features/layout/index.ts
  • frontends/ui/src/features/layout/store.spec.ts
  • frontends/ui/src/app/providers.tsx
  • frontends/ui/src/features/layout/components/CitationCard.tsx
  • frontends/ui/src/features/chat/components/UserMessage.tsx
  • frontends/ui/src/features/layout/components/FileCard.tsx
  • frontends/ui/src/features/layout/components/AgentsTab.tsx
  • frontends/ui/src/features/chat/lib/session-activity.ts
  • frontends/ui/src/features/layout/components/DataConnectionCard.tsx
  • frontends/ui/src/features/layout/components/TaskCard.tsx
  • frontends/ui/src/features/layout/components/ThinkingTab.tsx
  • frontends/ui/src/features/layout/components/TasksTab.tsx
  • frontends/ui/src/features/layout/components/ThoughtCard.tsx
  • frontends/ui/src/features/chat/components/AgentResponse.tsx
  • frontends/ui/src/features/layout/components/ReportTab.tsx
  • frontends/ui/src/features/layout/components/AgentsTab.spec.tsx
  • frontends/ui/src/features/layout/components/ReportCard.tsx
  • frontends/ui/src/features/chat/components/AgentPrompt.spec.tsx
  • frontends/ui/src/features/layout/components/ThoughtCard.spec.tsx
  • frontends/ui/src/features/layout/components/InputArea.tsx
  • frontends/ui/src/features/layout/components/ReportTab.spec.tsx
  • frontends/ui/src/features/layout/components/AgentCard.spec.tsx
  • frontends/ui/src/features/layout/components/AgentCard.tsx
  • frontends/ui/src/features/layout/components/DataSourcesPanel.tsx
  • frontends/ui/src/features/chat/components/ChatThinking.spec.tsx
  • frontends/ui/src/features/layout/components/DataConnectionsTab.tsx
  • frontends/ui/src/features/layout/components/FileSourcesTab.tsx
  • frontends/ui/src/features/layout/components/MainLayout.spec.tsx
  • frontends/ui/src/features/chat/components/AgentPrompt.tsx
  • frontends/ui/src/features/chat/components/AgentResponse.spec.tsx
  • frontends/ui/src/features/layout/components/ThinkingTab.spec.tsx
  • frontends/ui/src/features/layout/components/MainLayout.tsx
  • frontends/ui/src/features/layout/components/FileSourceCard.tsx
  • frontends/ui/src/features/layout/components/FileSourceCard.spec.tsx
  • frontends/ui/src/features/chat/components/ChatThinking.tsx
  • frontends/ui/src/features/layout/components/ChatArea.spec.tsx
  • frontends/ui/src/features/layout/components/ResearchPanel.tsx
  • frontends/ui/src/features/layout/components/ChatArea.tsx
  • frontends/ui/src/features/layout/components/AppBar.spec.tsx
  • frontends/ui/src/app/globals.css
  • frontends/ui/src/features/layout/components/SessionsPanel.tsx
  • frontends/ui/src/features/layout/components/SessionsPanel.spec.tsx
  • frontends/ui/src/features/layout/components/AppBar.tsx
🪛 Stylelint (17.14.0)
frontends/ui/src/app/globals.css

[error] 130-130: Expected "optimizeLegibility" to be "optimizelegibility" (value-keyword-case)

(value-keyword-case)

🔇 Additional comments (52)
frontends/ui/src/features/layout/components/CitationCard.tsx (1)

62-64: LGTM!

Also applies to: 81-81, 94-100

frontends/ui/src/features/layout/components/FileSourceCard.spec.tsx (1)

9-9: LGTM!

Also applies to: 51-58, 83-83, 143-143, 155-155

frontends/ui/src/features/layout/components/FileSourceCard.tsx (1)

143-144: LGTM!

Also applies to: 194-194, 205-207, 227-236, 248-248, 262-270

frontends/ui/src/shared/lib/scroll.ts (1)

1-26: 📐 Maintainability & Code Quality

Confirm the required UI build validation.

The PR summary covers lint, type-check, tests, browser verification, and screenshots, but not the required build result. Please confirm npm run build completed successfully.

Source: Coding guidelines

frontends/ui/src/shared/lib/scroll.spec.ts (1)

4-42: LGTM!

frontends/ui/src/features/layout/components/AgentsTab.tsx (1)

5-44: LGTM!

Also applies to: 61-78

frontends/ui/src/features/layout/components/AgentsTab.spec.tsx (1)

4-119: LGTM!

frontends/ui/src/features/layout/components/ReportCard.tsx (1)

50-50: LGTM!

Also applies to: 98-98, 113-118

frontends/ui/src/features/layout/components/ReportTab.spec.tsx (1)

36-42: LGTM!

Also applies to: 117-140

frontends/ui/src/features/layout/components/AgentCard.spec.tsx (1)

12-147: LGTM!

Also applies to: 149-195, 205-231

frontends/ui/src/features/layout/components/AgentCard.tsx (1)

7-62: LGTM!

Also applies to: 76-89, 96-100, 110-139

frontends/ui/src/features/layout/components/MainLayout.spec.tsx (1)

18-24: LGTM!

Also applies to: 50-51, 63-64, 103-104, 121-125, 169-170, 222-226

frontends/ui/src/features/layout/components/MainLayout.tsx (1)

9-12: LGTM!

Also applies to: 22-34, 38-42, 62-64, 96-96, 143-163, 208-213

frontends/ui/src/features/layout/components/AppBar.tsx (1)

18-22: LGTM!

Also applies to: 62-81, 106-106, 127-128, 153-173

frontends/ui/src/features/layout/components/AppBar.spec.tsx (1)

9-13: LGTM!

Also applies to: 47-48, 74-75, 82-83, 102-122, 133-139, 165-166, 187-188, 205-209, 229-235

frontends/ui/src/features/layout/components/SessionsPanel.spec.tsx (1)

4-27: LGTM!

Also applies to: 79-90, 105-105, 129-162, 176-190, 216-229, 239-298, 376-399, 420-456, 485-527, 545-551, 559-600, 640-648

frontends/ui/src/features/layout/components/SessionsPanel.tsx (1)

7-417: LGTM!

Also applies to: 425-745

frontends/ui/src/features/layout/components/DataSourcesPanel.spec.tsx (1)

233-237: Target the panel wrapper directly.

This selector remains descendant-wide and can be satisfied by another hidden div. Assert that container.firstElementChild has aria-hidden="true".

frontends/ui/src/features/layout/store.spec.ts (1)

200-202: LGTM!

frontends/ui/src/features/layout/components/DataSourcesPanel.tsx (2)

14-23: LGTM!

Also applies to: 90-126


220-447: 📐 Maintainability & Code Quality

Confirm the required production build validation.

The PR reports lint, type-check, tests, and browser verification, but not the required npm run build result.

As per coding guidelines, “Run npm lint, type-check, and build validation for UI changes in frontends/ui.”

Source: Coding guidelines

frontends/ui/src/features/layout/components/FileSourcesTab.tsx (1)

19-24: LGTM!

Also applies to: 40-46, 59-71, 86-112, 121-121, 128-129, 142-171, 187-187, 197-226, 241-241

frontends/ui/src/features/layout/components/SettingsPanel.tsx (1)

68-70: LGTM!

frontends/ui/src/features/layout/components/SourceCard.tsx (1)

81-108: LGTM!

frontends/ui/src/features/layout/components/TaskCard.spec.tsx (1)

47-69: LGTM!

Also applies to: 103-103

frontends/ui/src/features/layout/components/DataConnectionCard.tsx (2)

15-17: LGTM!

Also applies to: 111-120, 133-144


111-120: 📐 Maintainability & Code Quality

Record the required build validation.

The PR summary records lint, type-check, tests, and browser screenshots, but not the required production build validation. As per coding guidelines, “Run npm lint, type-check, and build validation for UI changes in frontends/ui.”

Source: Coding guidelines

frontends/ui/src/features/layout/components/DataConnectionsTab.tsx (1)

18-18: LGTM!

Also applies to: 104-107

frontends/ui/src/features/layout/components/ReportTab.tsx (1)

17-27: LGTM!

Also applies to: 40-61, 103-148

frontends/ui/src/features/layout/components/ResearchPanel.tsx (1)

95-100: LGTM!

Also applies to: 178-287

frontends/ui/src/features/layout/components/TaskCard.tsx (1)

9-40: LGTM!

Also applies to: 58-75

frontends/ui/src/features/layout/components/TasksTab.tsx (1)

27-93: LGTM!

frontends/ui/src/features/layout/components/FileCard.tsx (1)

189-192: LGTM!

frontends/ui/src/features/layout/components/ThinkingTab.spec.tsx (1)

9-12: LGTM!

Also applies to: 24-30, 42-50, 62-86, 99-155

frontends/ui/src/features/layout/components/ThinkingTab.tsx (2)

7-20: 📐 Maintainability & Code Quality

Complete the required production build validation.

The supplied PR evidence covers lint, type-check, tests, and browser verification, but does not explicitly confirm npm run build.

As per coding guidelines, “Run npm lint, type-check, and build validation for UI changes in frontends/ui.”

Source: Coding guidelines


22-67: LGTM!

Also applies to: 69-81, 106-147, 149-226

frontends/ui/src/features/layout/components/ThoughtCard.spec.tsx (1)

30-33: LGTM!

Also applies to: 137-137, 164-166, 183-183

frontends/ui/src/features/layout/components/ThoughtCard.tsx (1)

22-22: LGTM!

Also applies to: 83-96, 109-110, 119-119, 128-142, 157-187

frontends/ui/src/features/layout/index.ts (1)

31-32: 🎯 Functional Correctness

Remove the ToolCallInfo barrel export warning. No in-repo consumer imports ToolCallInfo from @/features/layout; it’s only used via ./components/ToolCallCard, so dropping that re-export does not break current callers.

			> Likely an incorrect or invalid review comment.
frontends/ui/src/features/layout/components/ChatArea.tsx (2)

219-219: Restore actionable file handling instead of the inert status row.

The retry callback is still empty and file messages still omit retry, cancel, and delete controls. This is the same unresolved finding from the previous review.

Also applies to: 279-285, 308-316, 433-449


17-210: LGTM!

Also applies to: 221-278, 286-307, 317-432, 450-576

frontends/ui/src/features/chat/lib/session-activity.ts (1)

17-21: LGTM!

frontends/ui/src/features/chat/components/AgentResponse.spec.tsx (1)

9-80: LGTM!

Also applies to: 91-97, 141-150, 162-216

frontends/ui/src/features/chat/components/AgentResponse.tsx (1)

14-26: LGTM!

Also applies to: 65-92, 95-97, 110-111, 131-229

frontends/ui/src/features/layout/components/ChatArea.autoscroll.spec.tsx (1)

1-132: LGTM!

frontends/ui/src/features/layout/components/ChatArea.spec.tsx (1)

59-68: LGTM!

Also applies to: 273-296, 341-355, 379-389, 404-442

frontends/ui/src/features/layout/components/InputArea.tsx (3)

25-25: LGTM!

Also applies to: 173-199


337-408: 📐 Maintainability & Code Quality

Confirm the required production validation commands.

The supplied PR evidence covers lint, type-check, tests, screenshots, and browser verification, but does not explicitly confirm npm run test:ci and npm run build.

As per coding guidelines, “Run npm lint, type-check, and build validation for UI changes” and validate visible changes with “npm run test:ci.”

Also applies to: 510-531

Source: Coding guidelines


152-157: 🩺 Stability & Availability

disconnect() already handles stop semantics. It marks the close intentional, clears isStreaming/isLoading, and suppresses reconnect churn; the stop path is already covered in use-websocket-chat.spec.ts.

			> Likely an incorrect or invalid review comment.
frontends/ui/src/features/chat/components/UserMessage.tsx (1)

19-19: LGTM!

Also applies to: 29-34

frontends/ui/src/app/page.tsx (1)

21-26: LGTM!

frontends/ui/src/app/providers.tsx (1)

20-20: LGTM!

Also applies to: 138-138

Comment thread frontends/ui/src/app/globals.css
Comment thread frontends/ui/src/app/globals.css
Comment thread frontends/ui/src/features/chat/components/AgentPrompt.tsx
Comment thread frontends/ui/src/features/chat/components/AgentPrompt.tsx
Comment thread frontends/ui/src/features/chat/components/AgentResponse.tsx Outdated
Comment thread frontends/ui/src/features/layout/components/DataConnectionsTab.tsx
Comment thread frontends/ui/src/features/layout/components/DataSourcesPanel.tsx
Comment thread frontends/ui/src/features/layout/components/DataSourcesPanel.tsx Outdated
Comment thread frontends/ui/src/features/layout/components/DataSourcesPanel.tsx
Comment thread frontends/ui/src/features/layout/components/ThinkingTab.tsx Outdated
Signed-off-by: Manush Maheshwari <manushm@nvidia.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request READY FOR REVIEW UI/UX UI and UX related fixes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants