Skip to content

feat: Agent "superpower" content types - #96

Open
shanemac wants to merge 3 commits into
mainfrom
claude/slack-session-w71uqv
Open

feat: Agent "superpower" content types#96
shanemac wants to merge 3 commits into
mainfrom
claude/slack-session-w71uqv

Conversation

@shanemac

@shanemac shanemac commented Jun 23, 2026

Copy link
Copy Markdown

What

Builds the five dynamic agent content cards from the Slack thread — the "5 components every agent needs," rendered as rich content types that show how Convos works for the user and surface the right thing at the right time.

Bucket Content type What it shows
Thinking agentThinking Live reasoning steps while the agent works; collapses to a summary when done
Sources agentSources Citations/references backing an answer (tap to open)
Action agentAction A tool call/action, with Approve/Decline when it needs the user
Memory agentMemory What the agent remembers — stored with the user, not the model
Suggestions agentSuggestions Tappable follow-up prompts to keep the conversation moving

How

Self-contained module under features/conversation/conversation-chat/conversation-message/agent-content/:

  • agent-content.types.ts — discriminated union + per-type schemas
  • agent-content.assertions.ts — type guards
  • agent-card.tsx — shared expandable card primitive (icon badge, title/subtitle, collapsible body)
  • agent-content-{thinking,sources,action,memory,suggestions}.tsx — the five render components
  • agent-content.tsx — dispatcher mirroring the pattern in conversation-message.tsx
  • agent-content.fixtures.ts — mock data

Scope of this PR

  • UI components + types only with mock/local data. Intentionally decoupled from the XMTP-bound IConversationMessage union, so there's no wire-format codec yet and the protocol conversion layer is untouched. Encode/decode + send/receive can come in a follow-up.
  • Added an "Agent content examples" dev screen (reachable from App Settings) that renders every card with fixtures for review.

Testing

Matches existing design-system conventions (themed styles, presets, tokens). node_modules couldn't be installed in this environment (package registry blocked), so a full tsc run wasn't possible here — every component API was verified against source instead. Worth a local yarn typecheck before merge.

🤖 Generated with Claude Code


Generated by Claude Code

Note

Add agent 'superpower' content type components for thinking, actions, sources, memory, and suggestions

  • Defines a IAgentContent discriminated union in agent-content.types.ts covering five content categories: thinking, actions, sources, memory, and suggestions.
  • Adds a dispatcher component AgentContent that routes each union variant to a dedicated card component (AgentContentThinking, AgentContentAction, AgentContentSources, AgentContentMemory, AgentContentSuggestions).
  • Each card is built on a shared AgentCard base component that supports theming, icon accents, optional trailing content, and collapsible bodies.
  • Adds an AgentContentExamplesScreen accessible from App Settings that renders all content types using fixture data for preview.
  • Registers the new AgentContentExamples route in app-navigator.tsx and adds the row to settings in app-settings.screen.tsx.

Macroscope summarized 885efe6.

Summary by CodeRabbit

  • New Features
    • Added visual cards displaying agent reasoning steps, information sources, memory context, and suggested next steps within conversations.
    • Introduced action cards showing agent-proposed actions with approval/decline controls and status indicators.
    • Added a new demo screen accessible from app settings for viewing all agent content card examples.

Introduce the five dynamic agent content cards that show how Convos works
for the user, surfacing the right thing at the right time:

- Thinking      → live reasoning steps while the agent works
- Sources       → citations/references backing an answer
- Action        → a tool call/action, with approve/decline when needed
- Memory        → what the agent remembers (stored with the user)
- Suggestions   → tappable follow-up prompts

Implemented as a self-contained agent-content module (types, assertions,
a shared expandable AgentCard, per-type render components, a dispatcher
mirroring conversation-message.tsx, and mock fixtures). Kept decoupled
from the XMTP-bound message union so it has no wire-format codec yet and
doesn't touch the protocol conversion layer.

Added an "Agent content examples" dev screen (reachable from App Settings)
that renders every card with mock data for review.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Rov93B6jifGmgS6EGyw94c
@coderabbitai

coderabbitai Bot commented Jun 23, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

Introduces a complete "agent superpower" card UI system for conversation messages. Adds TypeScript type definitions and type guards for five agent content types (thinking, sources, action, memory, suggestions), a shared AgentCard primitive, five content-specific card components, an AgentContent dispatcher, mock fixtures, a dev demo screen, and navigation/settings wiring to access the demo.

Changes

Agent Content Cards UI System

Layer / File(s) Summary
Agent content type contracts and type guards
features/conversation/.../agent-content/agent-content.types.ts, features/conversation/.../agent-content/agent-content.assertions.ts
Defines IAgentContent as a discriminated union of five bucket types (thinking, sources, action, memory, suggestions) and exports predicate functions that narrow IAgentContent to each specific IAgent*Content shape.
AgentCard reusable card primitive
features/conversation/.../agent-content/agent-card.tsx
Implements the shared AgentCard component with accent-colored icon badge, title/subtitle header, optional collapsible expand/collapse with chevron, optional trailing content, and getAccentColor/withAlpha helpers.
Five content-type card components
features/conversation/.../agent-content/agent-content-thinking.tsx, agent-content-action.tsx, agent-content-memory.tsx, agent-content-sources.tsx, agent-content-suggestions.tsx
Adds AgentContentThinking (step list with active/done/pending status indicators), AgentContentAction (params, result, approve/decline buttons, ActionStatusBadge), AgentContentMemory (collapsible memory item rows), AgentContentSources (source rows with favicon and WebviewPreview navigation), and AgentContentSuggestions (tappable pill chips).
AgentContent dispatcher and fixtures
features/conversation/.../agent-content/agent-content.tsx, agent-content.fixtures.ts
Adds the AgentContent dispatcher that branches on runtime content type using the type guards, with a never exhaustive-check fallback, plus mock IAgentContent fixture data for all five types.
Dev demo screen, navigation, and settings wiring
features/conversation/.../agent-content/agent-content-examples.screen.tsx, navigation/navigation.types.tsx, navigation/app-navigator.tsx, features/app-settings/app-settings.screen.tsx
Adds AgentContentExamplesScreen that scrolls through all fixtures, registers the AgentContentExamples route in NavigationParamList and AppNavigator, and adds an "Agent content examples" entry in app settings.

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant AgentContentExamplesScreen
  participant AgentContent
  participant TypeGuards as isAgent*Content
  participant CardComponent as AgentContentThinking/Action/Memory/Sources/Suggestions

  User->>AgentContentExamplesScreen: navigates to AgentContentExamples route
  AgentContentExamplesScreen->>AgentContent: renders each fixture from allAgentContentFixtures
  AgentContent->>TypeGuards: checks agentContent.type via isAgentThinkingContent, isAgentSourcesContent, etc.
  TypeGuards-->>AgentContent: narrows to matching IAgent*Content
  AgentContent->>CardComponent: renders matched card with content prop
  CardComponent-->>User: displays themed AgentCard with content-specific layout
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 Hop hop, a new card stack appears!
Five little agents with badges and gears,
Thinking and sources and actions in rows,
Memory stacked high, and suggestions it shows.
The rabbit built cards with a collapsible cheer —
Now dev screens and nav make the demo path clear! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 10.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately and concisely summarizes the main change: introducing five new agent content types as UI components, matching the PR's primary objective.
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.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/slack-session-w71uqv

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@macroscopeapp

macroscopeapp Bot commented Jun 23, 2026

Copy link
Copy Markdown

Approvability

Verdict: Needs human review

This PR introduces a substantial new feature with five new agent content type components, new types, navigation changes, and user interaction flows (approve/decline actions). New features of this scope warrant human review regardless of the author's admin status.

You can customize Macroscope's approvability policy. Learn more.

ThemedStyle<ViewStyle> isn't assignable to an Image's style prop, which
would fail the tsc check.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Rov93B6jifGmgS6EGyw94c

@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: 3

🧹 Nitpick comments (4)
features/conversation/conversation-chat/conversation-message/agent-content/agent-card.tsx (3)

1-2: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Alias third-party imports to match repository convention.

Imports from external libraries should use as aliases for source clarity per repo standard.

As per coding guidelines: “When importing types or functions from external libraries, rename them to clearly indicate their source. Use the 'as' keyword to rename imports from third-party libraries.”

Proposed change
-import { memo, ReactNode, useState } from "react"
-import { ViewStyle } from "react-native"
+import { memo as reactMemo, ReactNode as ReactReactNode, useState as reactUseState } from "react"
+import { ViewStyle as RNViewStyle } from "react-native"
...
-export const AgentCard = memo(function AgentCard(props: IAgentCardProps) {
+export const AgentCard = reactMemo(function AgentCard(props: IAgentCardProps) {
...
-  const [expanded, setExpanded] = useState(defaultExpanded)
+  const [expanded, setExpanded] = reactUseState(defaultExpanded)
...
-const $card: ThemedStyle<ViewStyle> = ({ colors, spacing, borderRadius, borderWidth }) => ({
+const $card: ThemedStyle<RNViewStyle> = ({ colors, spacing, borderRadius, borderWidth }) => ({
🤖 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
`@features/conversation/conversation-chat/conversation-message/agent-content/agent-card.tsx`
around lines 1 - 2, The imports from external libraries (react and react-native)
need to be aliased to match repository conventions for clarity. In the import
statements at the top of the file, add aliases using the `as` keyword for all
imported items: memo, ReactNode, useState from the "react" import, and ViewStyle
from the "react-native" import. This makes the source of each imported item
explicit and improves code readability when these items are used throughout the
component.

Source: Coding guidelines


81-87: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Replace render ternary with an early-return style branch.

Line 81 uses a render ternary for header wrapping; switch to a precomputed branch/early-return pattern to align with the TSX rendering guideline.

As per coding guidelines: “Prefer early returns over ternaries in React component render logic.”

Proposed change
+  const headerContent = collapsible ? (
+    <Pressable withHaptics onPress={() => setExpanded((prev) => !prev)}>
+      {Header}
+    </Pressable>
+  ) : (
+    Header
+  )
+
   return (
     <VStack style={themed($card)}>
-      {collapsible ? (
-        <Pressable withHaptics onPress={() => setExpanded((prev) => !prev)}>
-          {Header}
-        </Pressable>
-      ) : (
-        Header
-      )}
+      {headerContent}
 
       {(!collapsible || expanded) && !!children && (
         <VStack style={themed($body)}>{children}</VStack>
       )}
     </VStack>
   )
🤖 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
`@features/conversation/conversation-chat/conversation-message/agent-content/agent-card.tsx`
around lines 81 - 87, The Header rendering logic uses a ternary operator to
conditionally wrap the Header in a Pressable component based on the collapsible
prop. Refactor this to use an early-return pattern instead: check if collapsible
is false and return the Header directly without the Pressable wrapper, then
render the Pressable-wrapped Header with the setExpanded callback for the truthy
case. This aligns with the guideline to prefer early returns over ternaries in
React component render logic.

Source: Coding guidelines


19-22: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Trim obvious inline/JSDoc comments in this TSX component.

These comments mostly duplicate what prop names and function bodies already express; keeping only non-obvious rationale will improve signal.

As per coding guidelines: “Don't add comments for obvious code… Avoid verbose JSDoc-style documentation when TypeScript types already provide this information.”

Also applies to: 27-34, 114-115

🤖 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
`@features/conversation/conversation-chat/conversation-message/agent-content/agent-card.tsx`
around lines 19 - 22, Remove or significantly simplify the JSDoc comments for
the props and other code in the agent-card.tsx component that simply restate
what the code already expresses. Specifically, trim the verbose comments for the
`trailing` and `collapsible` props (in the diff area at lines 19-22), as well as
similar obvious comments found at lines 27-34 and 114-115. Keep only comments
that explain non-obvious rationale or important implementation details that
cannot be inferred from the prop names and TypeScript types themselves. This
will improve code readability by reducing redundant documentation.

Source: Coding guidelines

features/conversation/conversation-chat/conversation-message/agent-content/agent-content.types.ts (1)

3-20: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Reduce verbose commentary in this TypeScript types module.

These block comments restate what the type names and fields already communicate; trimming them will keep the file cleaner and aligned with the repo TS style.

As per coding guidelines: “Don't add comments for obvious code… Avoid verbose JSDoc-style documentation when TypeScript types already provide this information.”

Also applies to: 28-30, 48-50, 65-67, 86-88, 101-103, 115-117

🤖 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
`@features/conversation/conversation-chat/conversation-message/agent-content/agent-content.types.ts`
around lines 3 - 20, Remove or significantly reduce the verbose JSDoc comment
block at the start of the agent-content.types.ts file that explains the five
buckets of agent superpowers, as the type names and field structure already
communicate this information clearly. Apply the same principle to trim verbose
comments at the other specified line ranges (28-30, 48-50, 65-67, 86-88,
101-103, 115-117) throughout the file. Keep only essential, non-obvious comments
that add value beyond what the TypeScript type definitions themselves convey,
following the repository's style guideline of avoiding verbose JSDoc-style
documentation when types are already self-explanatory.

Source: Coding guidelines

🤖 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
`@features/conversation/conversation-chat/conversation-message/agent-content/agent-content-examples.screen.tsx`:
- Around line 14-17: Remove the verbose JSDoc comment block (the multi-line
comment starting with /** and ending with */) at the top of the
agent-content-examples.screen.tsx file. The component name already clearly
conveys its purpose as a demo screen for agent content examples, making the
detailed explanation redundant and unnecessary to maintain according to the
project's coding guidelines.

In
`@features/conversation/conversation-chat/conversation-message/agent-content/agent-content-sources.tsx`:
- Around line 58-66: The handlePress callback function currently passes
source.url directly to the WebviewPreview navigation without validating the URL
scheme, which could allow unsafe URI schemes to be executed. In the handlePress
function, add validation logic before the navigate call to ensure that
source.url only uses safe schemes (http or https). Check if the URL starts with
http:// or https:// and only proceed with navigation if this condition is true,
otherwise skip the navigation to prevent potentially dangerous scheme handlers
from being triggered.

In
`@features/conversation/conversation-chat/conversation-message/agent-content/agent-content-thinking.tsx`:
- Around line 72-76: The Text component in agent-content-thinking.tsx has an
invalid weight prop value of "regular" which is not supported by the component's
type definition; it only accepts values from typography.primary, which includes
"normal" instead. Replace the string literal "regular" with "normal" in the
weight prop of the Text component that checks step.status to fix the
type-checking error.

---

Nitpick comments:
In
`@features/conversation/conversation-chat/conversation-message/agent-content/agent-card.tsx`:
- Around line 1-2: The imports from external libraries (react and react-native)
need to be aliased to match repository conventions for clarity. In the import
statements at the top of the file, add aliases using the `as` keyword for all
imported items: memo, ReactNode, useState from the "react" import, and ViewStyle
from the "react-native" import. This makes the source of each imported item
explicit and improves code readability when these items are used throughout the
component.
- Around line 81-87: The Header rendering logic uses a ternary operator to
conditionally wrap the Header in a Pressable component based on the collapsible
prop. Refactor this to use an early-return pattern instead: check if collapsible
is false and return the Header directly without the Pressable wrapper, then
render the Pressable-wrapped Header with the setExpanded callback for the truthy
case. This aligns with the guideline to prefer early returns over ternaries in
React component render logic.
- Around line 19-22: Remove or significantly simplify the JSDoc comments for the
props and other code in the agent-card.tsx component that simply restate what
the code already expresses. Specifically, trim the verbose comments for the
`trailing` and `collapsible` props (in the diff area at lines 19-22), as well as
similar obvious comments found at lines 27-34 and 114-115. Keep only comments
that explain non-obvious rationale or important implementation details that
cannot be inferred from the prop names and TypeScript types themselves. This
will improve code readability by reducing redundant documentation.

In
`@features/conversation/conversation-chat/conversation-message/agent-content/agent-content.types.ts`:
- Around line 3-20: Remove or significantly reduce the verbose JSDoc comment
block at the start of the agent-content.types.ts file that explains the five
buckets of agent superpowers, as the type names and field structure already
communicate this information clearly. Apply the same principle to trim verbose
comments at the other specified line ranges (28-30, 48-50, 65-67, 86-88,
101-103, 115-117) throughout the file. Keep only essential, non-obvious comments
that add value beyond what the TypeScript type definitions themselves convey,
following the repository's style guideline of avoiding verbose JSDoc-style
documentation when types are already self-explanatory.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: e40fc646-05c1-43f8-b1f3-af23addbeffe

📥 Commits

Reviewing files that changed from the base of the PR and between 64ddd08 and 3cfd3db.

📒 Files selected for processing (14)
  • features/app-settings/app-settings.screen.tsx
  • features/conversation/conversation-chat/conversation-message/agent-content/agent-card.tsx
  • features/conversation/conversation-chat/conversation-message/agent-content/agent-content-action.tsx
  • features/conversation/conversation-chat/conversation-message/agent-content/agent-content-examples.screen.tsx
  • features/conversation/conversation-chat/conversation-message/agent-content/agent-content-memory.tsx
  • features/conversation/conversation-chat/conversation-message/agent-content/agent-content-sources.tsx
  • features/conversation/conversation-chat/conversation-message/agent-content/agent-content-suggestions.tsx
  • features/conversation/conversation-chat/conversation-message/agent-content/agent-content-thinking.tsx
  • features/conversation/conversation-chat/conversation-message/agent-content/agent-content.assertions.ts
  • features/conversation/conversation-chat/conversation-message/agent-content/agent-content.fixtures.ts
  • features/conversation/conversation-chat/conversation-message/agent-content/agent-content.tsx
  • features/conversation/conversation-chat/conversation-message/agent-content/agent-content.types.ts
  • navigation/app-navigator.tsx
  • navigation/navigation.types.tsx

Comment on lines +14 to +17
/**
* Dev/demo screen that renders every agent content card with mock data so the
* five "superpower" buckets can be reviewed without protocol plumbing.
*/

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Remove verbose JSDoc on the screen component.

This comment is descriptive but redundant with the component name and implementation; it adds maintenance overhead when behavior evolves.

✂️ Suggested change
-/**
- * Dev/demo screen that renders every agent content card with mock data so the
- * five "superpower" buckets can be reviewed without protocol plumbing.
- */
 export const AgentContentExamplesScreen = memo(function AgentContentExamplesScreen() {

As per coding guidelines, "**/*.{ts,tsx}: Don't add comments for obvious code ... Avoid verbose JSDoc-style documentation when TypeScript types already provide this information."

📝 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.

Suggested change
/**
* Dev/demo screen that renders every agent content card with mock data so the
* five "superpower" buckets can be reviewed without protocol plumbing.
*/
export const AgentContentExamplesScreen = memo(function AgentContentExamplesScreen() {
🤖 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
`@features/conversation/conversation-chat/conversation-message/agent-content/agent-content-examples.screen.tsx`
around lines 14 - 17, Remove the verbose JSDoc comment block (the multi-line
comment starting with /** and ending with */) at the top of the
agent-content-examples.screen.tsx file. The component name already clearly
conveys its purpose as a demo screen for agent content examples, making the
detailed explanation redundant and unnecessary to maintain according to the
project's coding guidelines.

Source: Coding guidelines

- Use "normal" instead of the invalid "regular" Text weight in the
  thinking step list (fixes a tsc error in this PR's code).
- Only open http(s) source URLs in the WebView, so unexpected URI
  schemes can't be forwarded to an external handler.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Rov93B6jifGmgS6EGyw94c
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants