Files
brave-core/components/resources
Aubrey Keus f7d5b68cc9 [AI Chat] Add deep research event parsing and UI rendering (#34082)
* [AI Chat] Add deep research event parsing and UI rendering

  Parse 12 deep research streaming event types from OAI response deltas
  (queries, analyzing, thinking, answer, progress, blindspots, complete,
  error, search/fetch/analysis status, iteration complete) and render them
  in the assistant response as an animated single-line progress indicator
  with elapsed timer, culminating in a final answer with inline citation
  links and a sources section.

Implements: https://github.com/brave/brave-browser/issues/53022

* [AI Chat] Address review feedback (#34082)

  - Move deep research parsing out of oai_parsing.cc into its own file,
    using the brave-chat.deepResearch.* custom object pattern
  - Add unit tests for all deep research event parsing
  - Consolidate deep research event types into a single mojom union
  - Use mojom enums for status fields instead of raw strings
  - Use uint32 with _count suffixes for count fields
  - Add DeepResearchUrlInfo struct for url/favicon pairs
  - Use constexpr key constants instead of inline string literals
  - Pass model_key by value instead of const optional ref
  - Extract frontend deep research logic into deep_research_utils.ts
  - Add Storybook stories for the deep research component
  - Add localized UI strings
  - Fix copyright year in new files

* [AI Chat] Address second round of review feedback (#34082)

  - Remove model_key parameter from ParseDeepResearchEvent; return
    mojom::ConversationEntryEventPtr directly and wrap at call site so
    model_key remains available for tool call handling
  - Replace static_cast<uint32_t> with base::saturated_cast<uint32_t> to
    clamp negative server values instead of wrapping
  - Match "started" status explicitly in ParseSearchStatusEvent and
    ParseAnalysisStatusEvent; return nullopt with VLOG(1) for unrecognized
    values instead of silently defaulting to kStarted
  - Fix alphabetical ordering of deep_research_parsing entries in BUILD.gn
  - Revert unrelated cosmetic changes in oai_parsing.cc
  - Add JSDoc to exported interfaces in deep_research_utils.ts
  - Add unit tests for unknown status rejection

* [AI Chat] Address third round of review feedback (#34082)

  - Remove disableLinkRestrictions bypass for deep research; use the same
    allowedLinks-based link validation as regular search since
    WebSourcesContentBlock is already emitted and extracted for deep
    research tools
  - Scope deep research event extraction to events after the last deep
    research ToolUseEvent to handle multiple runs in a single response
  - Memoize extractDeepResearchEvents with React.useMemo
  - Remove redundant nonDeepResearchEvents filter since AssistantEvent
    returns null for unhandled types
  - Use {...props} spread for DeepResearchProgressLine
  - Rename ambiguous `e` variables to descriptive names (search, analysis,
    thinking, etc.)
  - Fix stale "Memoize" comment

* [AI Chat] Return nullptr instead of nullopt from ParseDeepResearchEvent

  mojom::ConversationEntryEventPtr is already nullable, so wrapping it
  in std::optional is redundant. Return nullptr for parse failures instead.

* [AI Chat] Add missing deepResearchEvent to event templates

* Presubmit code formatting fix

* [AI Chat] Fix deep research progress hiding too early

  The deep research progress panel was hidden as soon as the
  completeEvent arrived, but the synthesis answer hasn't started
  streaming yet at that point. Track whether a completionEvent
  (the synthesis answer) has arrived after the tool call and use
  that to decide when to hide the progress panel instead.

* [AI Chat] Address review feedback (#34082)

  - Add GURL::is_valid() checks for parsed URLs in deep_research_parsing.cc
  - Remove duplicate mojom include already present in header
  - Pass deepResearch as single prop instead of 10 individual props
  - Simplify startTimeRef useEffect logic per reviewer suggestion
  - Type-safe iconName using IconName from @brave/leo/icons/meta
  - Replace hardcoded spacing/radius/font values with design system
    variables (--leo-spacing-*, --leo-radius-*, --leo-font-*)
  - Add TODO for elapsed timer inaccuracy on re-render
  - Add unit tests for extractDeepResearchEvents (21 tests)
  - Add unit tests for DeepResearchEvent component (8 tests)
  - Add DynamicProgress story with timed event sequence for animation

* [AI Chat] Recalibrate elapsed timer on progressEvent updates (#34082)

  Recalibrate startTimeRef on every progressEvent instead of only on
  first render, so the timer stays accurate when the UI re-mounts
  mid-research (e.g. sidebar toggle, move to new tab).

* [AI Chat] Simplify elapsed timer to count from component mount (#34082)

  Replace progressEvent-based time calibration with a simple counter
  that starts from when DeepResearchProgressLine mounts. Removes the
  startTimeRef recalibration logic and progressEvent dependency from
  ElapsedTimeCounter.
2026-03-04 11:56:04 -05:00
..