Skip to content

ref(seer): simplify block component states#115589

Merged
natemoo-re merged 40 commits into
masterfrom
nm/seer/ref-components
May 21, 2026
Merged

ref(seer): simplify block component states#115589
natemoo-re merged 40 commits into
masterfrom
nm/seer/ref-components

Conversation

@natemoo-re
Copy link
Copy Markdown
Member

@natemoo-re natemoo-re commented May 14, 2026

Deep refactor of Seer Agent chat components.

  • Replaces MarkedText renderer with the new Markdown component (see feat(scraps): Markdown component #115025), unblocks streaming animation, component customizatin
    • Fixes table overflow state
    • Adds copy button to code blocks
  • Consolidates state management, localize derived state from new BlockContext.
  • Splits the blockComponents.tsx into focused per-role modules (chat/assistant.tsx, chat/toolUse.tsx, chat/user.tsx) that match the actual data shapes from the backend
  • Moves issue short-ID linkification from postProcessLLMMarkdown into the Markdown Text component override
  • Replaces todosToMarkdown in favor of a direct TodoList component
  • Removes both styled(MarkedText) wrappers
  • Removes bubbled onClick handler—interaction can now be handled by <Markdown component={{ }} /> overrides
  • Removes onMouseEnter, onMouseExit callbacks—action buttons are toggled via CSS and now support :focus-within

@natemoo-re natemoo-re requested a review from JonasBa May 14, 2026 18:29
@github-actions github-actions Bot added the Scope: Frontend Automatically applied to PRs that change frontend components label May 14, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 14, 2026

📊 Type Coverage Diff

Metric Before After Delta
Coverage 93.62% 93.63% 🟢 +0.01%
Typed 135,520 135,511 🔴 -9
Untyped 9,230 9,227 🟢 -3
🔍 4 new type safety issues introduced

any-typed symbols (4 new)

File Line Detail
static/app/views/seerExplorer/components/chat/toolUse.tsx 91 toolLinkByCallId (var)
static/app/views/seerExplorer/components/chat/toolUse.tsx 92 map (var)
static/app/views/seerExplorer/components/chat/toolUse.tsx 120 toolLinkByCallId (var(binding))
static/app/views/seerExplorer/components/chat/toolUse.tsx 132 toolLinkParams (var)

This is informational only and does not block the PR.

@natemoo-re
Copy link
Copy Markdown
Member Author

@cursoragent bugbot review

@cursor
Copy link
Copy Markdown
Contributor

cursor Bot commented May 15, 2026

Bugbot Review Complete

I've completed a thorough review of this Seer Agent chat components refactor against production bug patterns. Here's what I found:

Summary

Overall: Clean refactor with good defensive coding practices. No high-confidence runtime bugs detected.

The code demonstrates solid engineering:

  • Consistent use of optional chaining (?.) for nullable access
  • Null coalescing operators (??) for default values
  • Array access with fallback values
  • Proper context validation

Findings

1. Type Safety (MEDIUM confidence) - Inherited from type definition

Location: static/app/views/seerExplorer/components/chat/toolUse.tsx:87-95

The type coverage bot correctly flagged Record<string, any> usage:

const toolLinkByCallId = useMemo(() => {
  const map = new Map<string, Record<string, any> | undefined>();
  (block.tool_results || []).forEach((result, idx) => {
    if (result?.tool_call_id) {
      map.set(result.tool_call_id, block.tool_links?.[idx]?.params);
    }
  });
  return map;
}, [block.tool_links, block.tool_results]);

Context: This matches the source type definition in types.tsx:69 where ToolLink.params is already defined as Record<string, any>. The any typing is inherited, not introduced by this PR.

Impact: Weakens type safety but unlikely to cause runtime errors since the code defensively accesses properties with optional chaining (toolLinkParams?.is_error, toolLinkParams?.empty_results).

Recommendation: Consider tightening the ToolLink.params type definition if the param shapes are known, but this is an architectural improvement, not a bug fix for this PR.


2. React Key Using Non-Unique Content (LOW confidence)

Location: static/app/views/seerExplorer/components/chat/toolUse.tsx:248

{todos.map(todo => {
  const checked = todo.status === 'completed';
  return (
    <Flex key={todo.content} as="li" gap="sm" align="center">

Issue: Using todo.content as a React key could cause rendering issues if multiple todos have identical content.

Impact: Low - todos typically have unique descriptions, but edge cases could cause list rendering bugs.

Fix suggestion:

// If TodoItem has an ID field, use that:
<Flex key={todo.id} as="li" gap="sm" align="center">

// Or combine with index as fallback:
{todos.map((todo, idx) => (
  <Flex key={`${todo.content}-${idx}`} as="li" gap="sm" align="center">

Positive Observations

Null safety: Consistent use of optional chaining throughout (block.message.tool_calls?.map, toolCall.id ? ..., etc.)
Array access: Protected with null coalescing (toolsUsed[idx] ?? '')
Type guards: Proper filtering of nullable tool links before processing
Context validation: useBlockContext throws a clear error if used outside provider
Hook dependencies: All useMemo dependency arrays appear correct

Conclusion

This refactor maintains or improves code quality compared to the original monolithic implementation. The type coverage regression is due to inherited type definitions, and the defensive coding patterns used make runtime errors unlikely. The only minor improvement would be using stable React keys for todo lists.

No blocking issues found. This PR is safe to merge from a bug pattern perspective.

Open in Web Open in Cursor 

Comment thread static/app/views/seerExplorer/components/chat/shared.tsx
Comment thread static/app/views/seerExplorer/components/chat/shared.tsx Outdated
@aliu39
Copy link
Copy Markdown
Member

aliu39 commented May 16, 2026

Code looks good, but testing in dev-ui the issue short IDs don't seem to render markdown links:
Screenshot 2026-05-15 at 5 02 27 PM

@aliu39
Copy link
Copy Markdown
Member

aliu39 commented May 16, 2026

Works inconsistently ("here's the breakdown..")

Screenshot 2026-05-15 at 5 03 49 PM

Link https://sentry.dev.getsentry.net:7999/issues/7306809142/events/c6582c5f284e4f8a9fd8a63745ce370a/

@aliu39
Copy link
Copy Markdown
Member

aliu39 commented May 16, 2026

Did we intend to limit the width of assistant/tool blocks here? After making drawer wider:

Screenshot 2026-05-15 at 5 06 20 PM

natemoo-re and others added 27 commits May 21, 2026 17:50
- Thread readOnly through BlockContext so BlockActionBar hides in
  read-only sessions (regression caught by Sentry review bot)
- Replace Record<string, any> with typed ToolLinkParams interface
  for known tool link metadata keys
- Split monolithic index.spec.tsx into colocated per-component test
  files (user.spec, assistant.spec, toolUse.spec)

Co-Authored-By: Claude Opus 4 <noreply@anthropic.com>
Co-authored-by: Priscila Oliveira <priscila.oliveira@sentry.io>
Co-authored-by: Priscila Oliveira <priscila.oliveira@sentry.io>
Co-authored-by: Priscila Oliveira <priscila.oliveira@sentry.io>
Replace styled components with scraps layout props and use
CopyToClipboardButton per review feedback.
Text and InlineCode overrides in SeerMarkdown can produce nested <a>
tags when the content is already inside a markdown link. Add a context
provider on the Link override so both skip linkification in that case.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Scope: Backend Automatically applied to PRs that change backend components Scope: Frontend Automatically applied to PRs that change frontend components

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants