fix(frontend): AutoPilot notification follow-ups — branding, UX, persistence, and cross-tab sync - #12428
Conversation
…istence, and cross-tab sync - Rename "Otto" to "AutoPilot" in all notification surfaces (browser notifications, document title, dialog, banner) - Change Agent Activity icon from Bell to Pulse (Phosphor) - Center buttons in the "Stay in the loop" notification permission dialog - Fix browser notification constructor for service worker / PWA contexts by using ServiceWorkerRegistration.showNotification() with fallback - Persist completedSessionIDs to localStorage so notification state survives page refresh - Sync completedSessionIDs across tabs via storage events so clearing in one tab updates all others Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
🔍 PR Overlap DetectionThis check compares your PR against all other open PRs targeting the same branch to detect potential merge conflicts early. 🟢 Low Risk — File Overlap OnlyThese PRs touch the same files but different sections (click to expand)
Summary: 0 conflict(s), 0 medium risk, 5 low risk (out of 5 PRs with file overlap) Auto-generated on push. Ignores: |
|
Note Reviews pausedIt 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 Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
WalkthroughRenames UI text from "Otto" to "AutoPilot", persists completed Copilot session IDs to localStorage with cross-tab synchronization, centralizes browser notification handling (including audio preloading), updates document.title to include completed-session counts, and swaps an icon and minor dialog footer styling. Changes
Sequence Diagram(s)sequenceDiagram
actor User
participant UI as "UI Components"
participant Store as "Copilot Store"
participant Storage as "localStorage"
participant Notif as "Browser Notification"
User->>UI: completes session
UI->>Store: addCompletedSession(sessionId)
Store->>Storage: persist COPILOT_COMPLETED_SESSIONS
Storage-->>Store: persist ack
Store-->>UI: state updated
UI->>Notif: showBrowserNotification("AutoPilot is ready", ...)
Notif->>User: notification shown
User->>Notif: click notification
Notif->>UI: navigate / focus session
rect rgba(100,150,200,0.5)
Storage->>Other: 'storage' event (COPILOT_COMPLETED_SESSIONS)
Other->>Store: loadCompletedSessions()
Store->>UI: update completedSessionIDs
UI->>UI: update document.title with count
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
autogpt_platform/frontend/src/app/(platform)/copilot/store.ts (1)
9-17: Consider validating parsed data is an array.If localStorage data is corrupted or tampered with,
JSON.parse(raw)might return a non-array value. Passing a non-iterable (like a number) tonew Set()would throw.🛡️ Defensive fix
function loadCompletedSessions(): Set<string> { const raw = storage.get(Key.COPILOT_COMPLETED_SESSIONS); if (!raw) return new Set(); try { - return new Set(JSON.parse(raw)); + const parsed = JSON.parse(raw); + return Array.isArray(parsed) ? new Set(parsed) : new Set(); } catch { return new Set(); } }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@autogpt_platform/frontend/src/app/`(platform)/copilot/store.ts around lines 9 - 17, The loadCompletedSessions function may pass a non-iterable result from JSON.parse(raw) into new Set(), causing a crash if stored data is corrupted; modify loadCompletedSessions to parse raw, verify Array.isArray(parsed) (and optionally filter entries to strings) before constructing and returning new Set(parsed), and fall back to new Set() if the parsed value is not an array or parsing fails (still preserving the outer try/catch behavior); reference the storage key Key.COPILOT_COMPLETED_SESSIONS and the function name loadCompletedSessions when applying the change.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In
`@autogpt_platform/frontend/src/app/`(platform)/copilot/useCopilotNotifications.ts:
- Around line 21-28: The SW path using
ServiceWorkerRegistration.showNotification lacks click-handling so notifications
won't navigate to sessions; update the code to always attach session info to the
notification and either (A) remove the SW-specific branch and always call
createFallbackNotification so onclick logic runs in-window, or (B) keep the SW
path but ensure any service worker includes a notificationclick listener that
reads event.notification.data.sessionID and uses
clients.matchAll/clients.openWindow to focus or open the URL for that session;
specifically add the data payload when calling showNotification in
useCopilotNotifications and implement the notificationclick handler in the
service worker to navigate to `/copilot/sessions/{sessionID}` (use
createFallbackNotification's session URL format) and call
event.notification.close(), using clients.matchAll({type:"window"}) and
client.focus() / clients.openWindow as needed.
---
Nitpick comments:
In `@autogpt_platform/frontend/src/app/`(platform)/copilot/store.ts:
- Around line 9-17: The loadCompletedSessions function may pass a non-iterable
result from JSON.parse(raw) into new Set(), causing a crash if stored data is
corrupted; modify loadCompletedSessions to parse raw, verify
Array.isArray(parsed) (and optionally filter entries to strings) before
constructing and returning new Set(parsed), and fall back to new Set() if the
parsed value is not an array or parsing fails (still preserving the outer
try/catch behavior); reference the storage key Key.COPILOT_COMPLETED_SESSIONS
and the function name loadCompletedSessions when applying the change.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 46455b85-2c05-4896-b684-6d02893a68e5
📒 Files selected for processing (7)
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatSidebar/ChatSidebar.tsxautogpt_platform/frontend/src/app/(platform)/copilot/components/NotificationBanner/NotificationBanner.tsxautogpt_platform/frontend/src/app/(platform)/copilot/components/NotificationDialog/NotificationDialog.tsxautogpt_platform/frontend/src/app/(platform)/copilot/store.tsautogpt_platform/frontend/src/app/(platform)/copilot/useCopilotNotifications.tsautogpt_platform/frontend/src/components/layout/Navbar/components/AgentActivityDropdown/AgentActivityDropdown.tsxautogpt_platform/frontend/src/services/storage/local-storage.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: types
- GitHub Check: Seer Code Review
- GitHub Check: end-to-end tests
- GitHub Check: Check PR Status
🧰 Additional context used
📓 Path-based instructions (15)
autogpt_platform/frontend/**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
autogpt_platform/frontend/**/*.{ts,tsx,js,jsx}: Use Node.js 21+ with pnpm package manager for frontend development
Always run 'pnpm format' for formatting and linting code in frontend development
autogpt_platform/frontend/**/*.{ts,tsx,js,jsx}: Runpnpm formatto auto-fix formatting issues before completing work
Runpnpm lintto check for lint errors and fix any that appear before completing work
Files:
autogpt_platform/frontend/src/services/storage/local-storage.tsautogpt_platform/frontend/src/app/(platform)/copilot/components/NotificationDialog/NotificationDialog.tsxautogpt_platform/frontend/src/app/(platform)/copilot/components/NotificationBanner/NotificationBanner.tsxautogpt_platform/frontend/src/app/(platform)/copilot/components/ChatSidebar/ChatSidebar.tsxautogpt_platform/frontend/src/components/layout/Navbar/components/AgentActivityDropdown/AgentActivityDropdown.tsxautogpt_platform/frontend/src/app/(platform)/copilot/useCopilotNotifications.tsautogpt_platform/frontend/src/app/(platform)/copilot/store.ts
autogpt_platform/frontend/**/*.{tsx,ts}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
autogpt_platform/frontend/**/*.{tsx,ts}: Use function declarations for components and handlers (not arrow functions) in React components
Only use arrow functions for small inline lambdas (map, filter, etc.) in React components
Use PascalCase for component names and camelCase with 'use' prefix for hook names in React
Use Tailwind CSS utilities only for styling in frontend components
Use design system components from 'src/components/' (atoms, molecules, organisms) in frontend development
Never use 'src/components/legacy/' in frontend code
Only use Phosphor Icons (@phosphor-icons/react) for icons in frontend components
Use generated API hooks from '@/app/api/generated/endpoints/' instead of deprecated 'BackendAPI' or 'src/lib/autogpt-server-api/'
Use React Query for server state (via generated hooks) in frontend development
Default to client components ('use client') in Next.js; only use server components for SEO or extreme TTFB needs
Use '' component for rendering errors in frontend UI; use toast notifications for mutation errors; use 'Sentry.captureException()' for manual exceptions
Separate render logic from data/behavior in React components; keep comments minimal (code should be self-documenting)
Files:
autogpt_platform/frontend/src/services/storage/local-storage.tsautogpt_platform/frontend/src/app/(platform)/copilot/components/NotificationDialog/NotificationDialog.tsxautogpt_platform/frontend/src/app/(platform)/copilot/components/NotificationBanner/NotificationBanner.tsxautogpt_platform/frontend/src/app/(platform)/copilot/components/ChatSidebar/ChatSidebar.tsxautogpt_platform/frontend/src/components/layout/Navbar/components/AgentActivityDropdown/AgentActivityDropdown.tsxautogpt_platform/frontend/src/app/(platform)/copilot/useCopilotNotifications.tsautogpt_platform/frontend/src/app/(platform)/copilot/store.ts
autogpt_platform/frontend/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
autogpt_platform/frontend/**/*.{ts,tsx}: No barrel files or 'index.ts' re-exports in frontend code
Regenerate API hooks with 'pnpm generate:api' after backend OpenAPI spec changes in frontend developmentRun
pnpm typesto check for type errors and fix any that appear before completing work
Files:
autogpt_platform/frontend/src/services/storage/local-storage.tsautogpt_platform/frontend/src/app/(platform)/copilot/components/NotificationDialog/NotificationDialog.tsxautogpt_platform/frontend/src/app/(platform)/copilot/components/NotificationBanner/NotificationBanner.tsxautogpt_platform/frontend/src/app/(platform)/copilot/components/ChatSidebar/ChatSidebar.tsxautogpt_platform/frontend/src/components/layout/Navbar/components/AgentActivityDropdown/AgentActivityDropdown.tsxautogpt_platform/frontend/src/app/(platform)/copilot/useCopilotNotifications.tsautogpt_platform/frontend/src/app/(platform)/copilot/store.ts
autogpt_platform/frontend/**/*.{js,jsx,ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
autogpt_platform/frontend/**/*.{js,jsx,ts,tsx}: Format frontend code usingpnpm format
Never use components fromsrc/components/__legacy__/*
Files:
autogpt_platform/frontend/src/services/storage/local-storage.tsautogpt_platform/frontend/src/app/(platform)/copilot/components/NotificationDialog/NotificationDialog.tsxautogpt_platform/frontend/src/app/(platform)/copilot/components/NotificationBanner/NotificationBanner.tsxautogpt_platform/frontend/src/app/(platform)/copilot/components/ChatSidebar/ChatSidebar.tsxautogpt_platform/frontend/src/components/layout/Navbar/components/AgentActivityDropdown/AgentActivityDropdown.tsxautogpt_platform/frontend/src/app/(platform)/copilot/useCopilotNotifications.tsautogpt_platform/frontend/src/app/(platform)/copilot/store.ts
autogpt_platform/frontend/src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
autogpt_platform/frontend/src/**/*.{ts,tsx}: Structure components asComponentName/ComponentName.tsx+useComponentName.ts+helpers.tsand use design system components fromsrc/components/(atoms, molecules, organisms)
Use generated API hooks from@/app/api/__generated__/endpoints/with patternuse{Method}{Version}{OperationName}and regenerate withpnpm generate:api
Use function declarations (not arrow functions) for components and handlers
Separate render logic from business logic with component.tsx + useComponent.ts + helpers.ts structure
Colocate state when possible, avoid creating large components, use sub-components in local/componentsfolder
Avoid large hooks, abstract logic intohelpers.tsfiles when sensible
Use arrow functions only for callbacks, not for component declarations
Avoid comments at all times unless the code is very complex
Do not useuseCallbackoruseMemounless asked to optimize a given function
autogpt_platform/frontend/src/**/*.{ts,tsx}: Use function declarations (not arrow functions) for components and handlers
Use type-safe generated API hooks via Orval + React Query for data fetching
Use React Query for server state management and co-locate UI state in components/hooks
Separate render logic (.tsx) from business logic (use*.tshooks)
Use only shadcn/ui (Radix UI primitives) with Tailwind CSS for UI components
Use Phosphor Icons only for all icon implementations
Use ErrorCard component for render errors, toast for mutations, and Sentry for exceptions
Use design system components fromsrc/components/(atoms, molecules, organisms)
Never usesrc/components/__legacy__/*components
Use generated API hooks from@/app/api/__generated__/endpoints/with patternuse{Method}{Version}{OperationName}
Use Tailwind CSS only for styling with design tokens
Do not useuseCallbackoruseMemounless asked to optimize a specific function
Never type withanyunless a variable/attribute can actually be of any type
Files:
autogpt_platform/frontend/src/services/storage/local-storage.tsautogpt_platform/frontend/src/app/(platform)/copilot/components/NotificationDialog/NotificationDialog.tsxautogpt_platform/frontend/src/app/(platform)/copilot/components/NotificationBanner/NotificationBanner.tsxautogpt_platform/frontend/src/app/(platform)/copilot/components/ChatSidebar/ChatSidebar.tsxautogpt_platform/frontend/src/components/layout/Navbar/components/AgentActivityDropdown/AgentActivityDropdown.tsxautogpt_platform/frontend/src/app/(platform)/copilot/useCopilotNotifications.tsautogpt_platform/frontend/src/app/(platform)/copilot/store.ts
autogpt_platform/frontend/**/*.{js,jsx,ts,tsx,css}
📄 CodeRabbit inference engine (AGENTS.md)
Use Tailwind CSS only for styling, use design tokens, and use Phosphor Icons only
Files:
autogpt_platform/frontend/src/services/storage/local-storage.tsautogpt_platform/frontend/src/app/(platform)/copilot/components/NotificationDialog/NotificationDialog.tsxautogpt_platform/frontend/src/app/(platform)/copilot/components/NotificationBanner/NotificationBanner.tsxautogpt_platform/frontend/src/app/(platform)/copilot/components/ChatSidebar/ChatSidebar.tsxautogpt_platform/frontend/src/components/layout/Navbar/components/AgentActivityDropdown/AgentActivityDropdown.tsxautogpt_platform/frontend/src/app/(platform)/copilot/useCopilotNotifications.tsautogpt_platform/frontend/src/app/(platform)/copilot/store.ts
autogpt_platform/frontend/src/**/*.ts
📄 CodeRabbit inference engine (AGENTS.md)
Do not type hook returns, let Typescript infer as much as possible
Files:
autogpt_platform/frontend/src/services/storage/local-storage.tsautogpt_platform/frontend/src/app/(platform)/copilot/useCopilotNotifications.tsautogpt_platform/frontend/src/app/(platform)/copilot/store.ts
autogpt_platform/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Never type with
any, if no types available useunknown
Files:
autogpt_platform/frontend/src/services/storage/local-storage.tsautogpt_platform/frontend/src/app/(platform)/copilot/components/NotificationDialog/NotificationDialog.tsxautogpt_platform/frontend/src/app/(platform)/copilot/components/NotificationBanner/NotificationBanner.tsxautogpt_platform/frontend/src/app/(platform)/copilot/components/ChatSidebar/ChatSidebar.tsxautogpt_platform/frontend/src/components/layout/Navbar/components/AgentActivityDropdown/AgentActivityDropdown.tsxautogpt_platform/frontend/src/app/(platform)/copilot/useCopilotNotifications.tsautogpt_platform/frontend/src/app/(platform)/copilot/store.ts
autogpt_platform/frontend/src/**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (autogpt_platform/frontend/CLAUDE.md)
Fully capitalize acronyms in symbols, e.g.
graphID,useBackendAPI
Files:
autogpt_platform/frontend/src/services/storage/local-storage.tsautogpt_platform/frontend/src/app/(platform)/copilot/components/NotificationDialog/NotificationDialog.tsxautogpt_platform/frontend/src/app/(platform)/copilot/components/NotificationBanner/NotificationBanner.tsxautogpt_platform/frontend/src/app/(platform)/copilot/components/ChatSidebar/ChatSidebar.tsxautogpt_platform/frontend/src/components/layout/Navbar/components/AgentActivityDropdown/AgentActivityDropdown.tsxautogpt_platform/frontend/src/app/(platform)/copilot/useCopilotNotifications.tsautogpt_platform/frontend/src/app/(platform)/copilot/store.ts
autogpt_platform/frontend/src/**/*.tsx
📄 CodeRabbit inference engine (AGENTS.md)
Component props should be
interface Props { ... }(not exported) unless the interface needs to be used outside the componentUse
type Props = { ... }(not exported) for component props unless used outside the component
Files:
autogpt_platform/frontend/src/app/(platform)/copilot/components/NotificationDialog/NotificationDialog.tsxautogpt_platform/frontend/src/app/(platform)/copilot/components/NotificationBanner/NotificationBanner.tsxautogpt_platform/frontend/src/app/(platform)/copilot/components/ChatSidebar/ChatSidebar.tsxautogpt_platform/frontend/src/components/layout/Navbar/components/AgentActivityDropdown/AgentActivityDropdown.tsx
autogpt_platform/frontend/src/app/(platform)/**/*.tsx
📄 CodeRabbit inference engine (AGENTS.md)
If adding protected frontend routes, update
frontend/lib/supabase/middleware.ts
Files:
autogpt_platform/frontend/src/app/(platform)/copilot/components/NotificationDialog/NotificationDialog.tsxautogpt_platform/frontend/src/app/(platform)/copilot/components/NotificationBanner/NotificationBanner.tsxautogpt_platform/frontend/src/app/(platform)/copilot/components/ChatSidebar/ChatSidebar.tsx
autogpt_platform/frontend/src/**/components/**/*.{ts,tsx}
📄 CodeRabbit inference engine (autogpt_platform/frontend/CLAUDE.md)
Put sub-components in a local
components/folder within the feature directory
Files:
autogpt_platform/frontend/src/app/(platform)/copilot/components/NotificationDialog/NotificationDialog.tsxautogpt_platform/frontend/src/app/(platform)/copilot/components/NotificationBanner/NotificationBanner.tsxautogpt_platform/frontend/src/app/(platform)/copilot/components/ChatSidebar/ChatSidebar.tsxautogpt_platform/frontend/src/components/layout/Navbar/components/AgentActivityDropdown/AgentActivityDropdown.tsx
autogpt_platform/frontend/src/**/[A-Z]*/**/*.{ts,tsx}
📄 CodeRabbit inference engine (autogpt_platform/frontend/CLAUDE.md)
Structure components as ComponentName/ComponentName.tsx + useComponentName.ts + helpers.ts
Files:
autogpt_platform/frontend/src/app/(platform)/copilot/components/NotificationDialog/NotificationDialog.tsxautogpt_platform/frontend/src/app/(platform)/copilot/components/NotificationBanner/NotificationBanner.tsxautogpt_platform/frontend/src/app/(platform)/copilot/components/ChatSidebar/ChatSidebar.tsxautogpt_platform/frontend/src/components/layout/Navbar/components/AgentActivityDropdown/AgentActivityDropdown.tsx
autogpt_platform/frontend/src/components/**/*.{tsx,ts}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Structure React components as: ComponentName/ComponentName.tsx + useComponentName.ts + helpers.ts (exception: small 3-4 line components can be inline; render-only components can be direct files)
Files:
autogpt_platform/frontend/src/components/layout/Navbar/components/AgentActivityDropdown/AgentActivityDropdown.tsx
autogpt_platform/frontend/src/**/use*.ts
📄 CodeRabbit inference engine (autogpt_platform/frontend/CLAUDE.md)
autogpt_platform/frontend/src/**/use*.ts: Extract component logic into custom hooks grouped by concern, with each hook in its own.tsfile
Do not type hook returns; let TypeScript infer types as much as possible
Files:
autogpt_platform/frontend/src/app/(platform)/copilot/useCopilotNotifications.ts
🧠 Learnings (9)
📓 Common learnings
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12356
File: autogpt_platform/backend/backend/copilot/constants.py:9-12
Timestamp: 2026-03-10T08:39:13.707Z
Learning: In Significant-Gravitas/AutoGPT PR `#12356`, the `COPILOT_SYNTHETIC_ID_PREFIX = "copilot-"` check in `create_auto_approval_record` (human_review.py) is intentional and safe. The `graph_exec_id` passed to this function comes from server-side `PendingHumanReview` DB records (not from user input); the API only accepts `node_exec_id` from users. Synthetic `copilot-*` IDs are only ever created server-side in `run_block.py`. The prefix skip avoids a DB lookup for a `AgentGraphExecution` record that legitimately does not exist for CoPilot sessions, while `user_id` scoping is enforced at the auth layer and on the resulting auto-approval record.
📚 Learning: 2026-02-26T10:12:58.845Z
Learnt from: 0ubbe
Repo: Significant-Gravitas/AutoGPT PR: 12207
File: autogpt_platform/frontend/src/components/ai-elements/conversation.tsx:0-0
Timestamp: 2026-02-26T10:12:58.845Z
Learning: Guideline: Do not apply dark mode CSS classes (e.g., dark:text-*) to copilot UI components until dark mode support is implemented. Applies to all copilot-related components (paths containing /copilot/). When reviewing, search for dark:* class names within copilot components and refactor to use conditional class sets or feature-flag gates, ensuring no dark-mode styles are present in the code paths that render copilot UI unless dark mode support is officially enabled.
Applied to files:
autogpt_platform/frontend/src/app/(platform)/copilot/components/NotificationDialog/NotificationDialog.tsxautogpt_platform/frontend/src/app/(platform)/copilot/components/NotificationBanner/NotificationBanner.tsxautogpt_platform/frontend/src/app/(platform)/copilot/components/ChatSidebar/ChatSidebar.tsx
📚 Learning: 2026-02-27T10:45:49.499Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12213
File: autogpt_platform/frontend/src/app/(platform)/copilot/tools/RunMCPTool/helpers.tsx:23-24
Timestamp: 2026-02-27T10:45:49.499Z
Learning: Prefer using generated OpenAPI types from '@/app/api/__generated__/' for payloads defined in openapi.json (e.g., MCPToolsDiscoveredResponse, MCPToolOutputResponse). Use inline TypeScript interfaces only for payloads that are SSE-stream-only and not exposed via OpenAPI. Apply this pattern to frontend tool components (e.g., RunMCPTool) and related areas where similar SSE/openapi-discrepancies occur; avoid re-implementing types when a generated type is available.
Applied to files:
autogpt_platform/frontend/src/app/(platform)/copilot/components/NotificationDialog/NotificationDialog.tsxautogpt_platform/frontend/src/app/(platform)/copilot/components/NotificationBanner/NotificationBanner.tsxautogpt_platform/frontend/src/app/(platform)/copilot/components/ChatSidebar/ChatSidebar.tsx
📚 Learning: 2026-02-04T16:49:42.490Z
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2026-02-04T16:49:42.490Z
Learning: Applies to autogpt_platform/frontend/**/*.{tsx,ts} : Use '<ErrorCard />' component for rendering errors in frontend UI; use toast notifications for mutation errors; use 'Sentry.captureException()' for manual exceptions
Applied to files:
autogpt_platform/frontend/src/app/(platform)/copilot/components/NotificationBanner/NotificationBanner.tsx
📚 Learning: 2026-03-11T08:40:53.404Z
Learnt from: kcze
Repo: Significant-Gravitas/AutoGPT PR: 12328
File: autogpt_platform/frontend/src/app/(platform)/copilot/useLoadMoreMessages.ts:49-61
Timestamp: 2026-03-11T08:40:53.404Z
Learning: In `autogpt_platform/frontend/src/app/(platform)/copilot/useLoadMoreMessages.ts`, clearing `olderMessages` (and resetting `oldestSequence`/`hasMore`) when `initialOldestSequence` shifts on the same session is intentional. Pages already fetched were based on a now-stale cursor; retaining them risks sequence gaps or duplicates. `ScrollPreserver` keeps the currently visible viewport intact, so only unvisited older pages are dropped. This is a deliberate safe-refetch design tradeoff.
Applied to files:
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatSidebar/ChatSidebar.tsxautogpt_platform/frontend/src/app/(platform)/copilot/store.ts
📚 Learning: 2026-02-04T16:49:42.490Z
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2026-02-04T16:49:42.490Z
Learning: Applies to autogpt_platform/frontend/**/*.{tsx,ts} : Only use Phosphor Icons (phosphor-icons/react) for icons in frontend components
Applied to files:
autogpt_platform/frontend/src/components/layout/Navbar/components/AgentActivityDropdown/AgentActivityDropdown.tsx
📚 Learning: 2026-02-26T21:29:44.105Z
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: autogpt_platform/frontend/CLAUDE.md:0-0
Timestamp: 2026-02-26T21:29:44.105Z
Learning: Applies to autogpt_platform/frontend/src/**/*.{ts,tsx} : Use Phosphor Icons only for all icon implementations
Applied to files:
autogpt_platform/frontend/src/components/layout/Navbar/components/AgentActivityDropdown/AgentActivityDropdown.tsx
📚 Learning: 2026-02-26T21:29:44.105Z
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: autogpt_platform/frontend/CLAUDE.md:0-0
Timestamp: 2026-02-26T21:29:44.105Z
Learning: Applies to autogpt_platform/frontend/src/**/*.{ts,tsx,js,jsx} : Fully capitalize acronyms in symbols, e.g. `graphID`, `useBackendAPI`
Applied to files:
autogpt_platform/frontend/src/components/layout/Navbar/components/AgentActivityDropdown/AgentActivityDropdown.tsx
📚 Learning: 2026-02-04T16:49:42.490Z
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2026-02-04T16:49:42.490Z
Learning: Applies to autogpt_platform/frontend/**/*.{tsx,ts} : Use generated API hooks from '@/app/api/__generated__/endpoints/' instead of deprecated 'BackendAPI' or 'src/lib/autogpt-server-api/*'
Applied to files:
autogpt_platform/frontend/src/components/layout/Navbar/components/AgentActivityDropdown/AgentActivityDropdown.tsx
🔇 Additional comments (9)
autogpt_platform/frontend/src/components/layout/Navbar/components/AgentActivityDropdown/AgentActivityDropdown.tsx (1)
9-9: Pulse icon replacement looks good and consistent.The import and JSX usage are both clean, and the change stays within the project’s Phosphor-only icon rule without affecting behavior.
Based on learnings: Applies to
autogpt_platform/frontend/**/*.{tsx,ts}— “Only use Phosphor Icons (phosphor-icons/react) for icons in frontend components.”Also applies to: 33-33
autogpt_platform/frontend/src/app/(platform)/copilot/components/NotificationDialog/NotificationDialog.tsx (1)
79-92: LGTM!The branding update from "Otto" to "AutoPilot" and the centered footer buttons improve consistency across the notification surfaces. The implementation correctly uses Tailwind's
justify-centerfor button alignment.autogpt_platform/frontend/src/services/storage/local-storage.ts (1)
18-18: LGTM!The new
COPILOT_COMPLETED_SESSIONSkey follows the established naming convention and integrates cleanly with the existing copilot-related storage keys.autogpt_platform/frontend/src/app/(platform)/copilot/components/NotificationBanner/NotificationBanner.tsx (1)
58-61: LGTM!The branding update to "AutoPilot" is consistent with the other notification surfaces in this PR.
autogpt_platform/frontend/src/app/(platform)/copilot/store.ts (1)
58-76: LGTM on persistence integration.The initialization from localStorage and the persist calls on add/clear operations correctly maintain state across page reloads. The
setStateusage in the cross-tab listener (inuseCopilotNotifications.ts) properly avoids re-triggering persistence, preventing infinite loops.autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatSidebar/ChatSidebar.tsx (1)
122-128: LGTM!The document title update to "AutoPilot is ready" maintains consistency with the title format used in
useCopilotNotifications.ts. The logic correctly clears the indicator and updates the title when navigating to a completed session.autogpt_platform/frontend/src/app/(platform)/copilot/useCopilotNotifications.ts (3)
40-47: Notification click navigation approach looks reasonable.Using
pushState+dispatchEvent(popstate)should trigger nuqs's query state updates without a full page reload. This is a valid approach for programmatic navigation.
158-179: LGTM on cross-tab synchronization.The storage event handler correctly:
- Filters for only the
COPILOT_COMPLETED_SESSIONSkey- Uses
setStatedirectly to avoid re-triggering persistence (preventing cross-tab ping-pong)- Updates
document.titleto reflect the synced state- Properly cleans up the event listener
67-71: LGTM on title synchronization.The preload effect correctly syncs the document title with persisted state on mount, ensuring the badge count is visible immediately after a page refresh when there are pending sessions.
…tification - Add Array.isArray guard in loadCompletedSessions for corrupted localStorage - Replace SW-specific notification path with try-catch around Notification constructor (no service worker exists in the codebase, and SW notifications lack onclick navigation support) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In
`@autogpt_platform/frontend/src/app/`(platform)/copilot/useCopilotNotifications.ts:
- Around line 155-160: The incoming storage snapshot is being treated as
authoritative in useCopilotNotifications, wiping out concurrent updates; instead
merge the incoming completedSessionIDs with the current store before writing. In
the handler that calls useCopilotUIStore.setState({ completedSessionIDs: next })
perform a union of the existing useCopilotUIStore.getState().completedSessionIDs
and the incoming next set (or otherwise reconcile by timestamp/operation), then
persist that merged set so the shared read-modify-write persistence path does
not clobber concurrent tab updates; update the storage-write codepath to always
read the latest store, merge, then write the merged set back to
localStorage/sessionStorage and only then call setState to ensure
last-write-wins across tabs is avoided.
- Around line 147-153: The storage-event handler in useCopilotNotifications.ts
currently does new Set(JSON.parse(e.newValue)) which will happily accept
non-array JSON (e.g., a string) and populate completedSessionIDs incorrectly;
change the logic in the try block to parse e.newValue into a temp value,
validate that Array.isArray(parsed) and that every element is a string, and only
then set next = new Set<string>(parsed) — otherwise set next = new Set<string>()
so cross-tab sync mirrors the array-shape validation used in the initial load
path; update references to next/completedSessionIDs accordingly.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 736b9a91-414c-45e6-b429-139827be6d69
📒 Files selected for processing (2)
autogpt_platform/frontend/src/app/(platform)/copilot/store.tsautogpt_platform/frontend/src/app/(platform)/copilot/useCopilotNotifications.ts
🚧 Files skipped from review as they are similar to previous changes (1)
- autogpt_platform/frontend/src/app/(platform)/copilot/store.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
- GitHub Check: lint
- GitHub Check: integration_test
- GitHub Check: end-to-end tests
- GitHub Check: types
- GitHub Check: Seer Code Review
- GitHub Check: Check PR Status
🧰 Additional context used
📓 Path-based instructions (10)
autogpt_platform/frontend/**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
autogpt_platform/frontend/**/*.{ts,tsx,js,jsx}: Use Node.js 21+ with pnpm package manager for frontend development
Always run 'pnpm format' for formatting and linting code in frontend development
autogpt_platform/frontend/**/*.{ts,tsx,js,jsx}: Runpnpm formatto auto-fix formatting issues before completing work
Runpnpm lintto check for lint errors and fix any that appear before completing work
Files:
autogpt_platform/frontend/src/app/(platform)/copilot/useCopilotNotifications.ts
autogpt_platform/frontend/**/*.{tsx,ts}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
autogpt_platform/frontend/**/*.{tsx,ts}: Use function declarations for components and handlers (not arrow functions) in React components
Only use arrow functions for small inline lambdas (map, filter, etc.) in React components
Use PascalCase for component names and camelCase with 'use' prefix for hook names in React
Use Tailwind CSS utilities only for styling in frontend components
Use design system components from 'src/components/' (atoms, molecules, organisms) in frontend development
Never use 'src/components/legacy/' in frontend code
Only use Phosphor Icons (@phosphor-icons/react) for icons in frontend components
Use generated API hooks from '@/app/api/generated/endpoints/' instead of deprecated 'BackendAPI' or 'src/lib/autogpt-server-api/'
Use React Query for server state (via generated hooks) in frontend development
Default to client components ('use client') in Next.js; only use server components for SEO or extreme TTFB needs
Use '' component for rendering errors in frontend UI; use toast notifications for mutation errors; use 'Sentry.captureException()' for manual exceptions
Separate render logic from data/behavior in React components; keep comments minimal (code should be self-documenting)
Files:
autogpt_platform/frontend/src/app/(platform)/copilot/useCopilotNotifications.ts
autogpt_platform/frontend/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
autogpt_platform/frontend/**/*.{ts,tsx}: No barrel files or 'index.ts' re-exports in frontend code
Regenerate API hooks with 'pnpm generate:api' after backend OpenAPI spec changes in frontend developmentRun
pnpm typesto check for type errors and fix any that appear before completing work
Files:
autogpt_platform/frontend/src/app/(platform)/copilot/useCopilotNotifications.ts
autogpt_platform/frontend/**/*.{js,jsx,ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
autogpt_platform/frontend/**/*.{js,jsx,ts,tsx}: Format frontend code usingpnpm format
Never use components fromsrc/components/__legacy__/*
Files:
autogpt_platform/frontend/src/app/(platform)/copilot/useCopilotNotifications.ts
autogpt_platform/frontend/src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
autogpt_platform/frontend/src/**/*.{ts,tsx}: Structure components asComponentName/ComponentName.tsx+useComponentName.ts+helpers.tsand use design system components fromsrc/components/(atoms, molecules, organisms)
Use generated API hooks from@/app/api/__generated__/endpoints/with patternuse{Method}{Version}{OperationName}and regenerate withpnpm generate:api
Use function declarations (not arrow functions) for components and handlers
Separate render logic from business logic with component.tsx + useComponent.ts + helpers.ts structure
Colocate state when possible, avoid creating large components, use sub-components in local/componentsfolder
Avoid large hooks, abstract logic intohelpers.tsfiles when sensible
Use arrow functions only for callbacks, not for component declarations
Avoid comments at all times unless the code is very complex
Do not useuseCallbackoruseMemounless asked to optimize a given function
autogpt_platform/frontend/src/**/*.{ts,tsx}: Use function declarations (not arrow functions) for components and handlers
Use type-safe generated API hooks via Orval + React Query for data fetching
Use React Query for server state management and co-locate UI state in components/hooks
Separate render logic (.tsx) from business logic (use*.tshooks)
Use only shadcn/ui (Radix UI primitives) with Tailwind CSS for UI components
Use Phosphor Icons only for all icon implementations
Use ErrorCard component for render errors, toast for mutations, and Sentry for exceptions
Use design system components fromsrc/components/(atoms, molecules, organisms)
Never usesrc/components/__legacy__/*components
Use generated API hooks from@/app/api/__generated__/endpoints/with patternuse{Method}{Version}{OperationName}
Use Tailwind CSS only for styling with design tokens
Do not useuseCallbackoruseMemounless asked to optimize a specific function
Never type withanyunless a variable/attribute can actually be of any type
Files:
autogpt_platform/frontend/src/app/(platform)/copilot/useCopilotNotifications.ts
autogpt_platform/frontend/**/*.{js,jsx,ts,tsx,css}
📄 CodeRabbit inference engine (AGENTS.md)
Use Tailwind CSS only for styling, use design tokens, and use Phosphor Icons only
Files:
autogpt_platform/frontend/src/app/(platform)/copilot/useCopilotNotifications.ts
autogpt_platform/frontend/src/**/*.ts
📄 CodeRabbit inference engine (AGENTS.md)
Do not type hook returns, let Typescript infer as much as possible
Files:
autogpt_platform/frontend/src/app/(platform)/copilot/useCopilotNotifications.ts
autogpt_platform/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Never type with
any, if no types available useunknown
Files:
autogpt_platform/frontend/src/app/(platform)/copilot/useCopilotNotifications.ts
autogpt_platform/frontend/src/**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (autogpt_platform/frontend/CLAUDE.md)
Fully capitalize acronyms in symbols, e.g.
graphID,useBackendAPI
Files:
autogpt_platform/frontend/src/app/(platform)/copilot/useCopilotNotifications.ts
autogpt_platform/frontend/src/**/use*.ts
📄 CodeRabbit inference engine (autogpt_platform/frontend/CLAUDE.md)
autogpt_platform/frontend/src/**/use*.ts: Extract component logic into custom hooks grouped by concern, with each hook in its own.tsfile
Do not type hook returns; let TypeScript infer types as much as possible
Files:
autogpt_platform/frontend/src/app/(platform)/copilot/useCopilotNotifications.ts
🧠 Learnings (1)
📚 Learning: 2026-02-26T21:29:44.105Z
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: autogpt_platform/frontend/CLAUDE.md:0-0
Timestamp: 2026-02-26T21:29:44.105Z
Learning: Applies to autogpt_platform/frontend/**/*.{ts,tsx} : Run `pnpm types` to check for type errors and fix any that appear before completing work
Applied to files:
autogpt_platform/frontend/src/app/(platform)/copilot/useCopilotNotifications.ts
🔇 Additional comments (1)
autogpt_platform/frontend/src/app/(platform)/copilot/useCopilotNotifications.ts (1)
15-33: Nice consolidation of the browser-notification path.Keeping the constructor and click-through navigation in
showBrowserNotificationmakes this behavior much harder to regress at future call sites.
Mirror the array-shape validation from loadCompletedSessions() in the storage event handler to guard against malformed localStorage payloads. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
♻️ Duplicate comments (1)
autogpt_platform/frontend/src/app/(platform)/copilot/useCopilotNotifications.ts (1)
160-163:⚠️ Potential issue | 🟠 MajorStale
storageevents can still overwrite newer local state.Line 162 applies each incoming snapshot as authoritative. With near-simultaneous writes from multiple tabs, delayed events can revert a newer set. Consider versioned reconciliation (e.g.,
updatedAt/ monotonic revision) or a merge policy in the persistence path to avoid clobbering.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@autogpt_platform/frontend/src/app/`(platform)/copilot/useCopilotNotifications.ts around lines 160 - 163, The current storage-event handler in useCopilotNotifications.ts blindly applies the incoming snapshot via useCopilotUIStore.setState({ completedSessionIDs: next }), which allows stale storage events to overwrite newer local state; fix by adding a simple reconciliation: persist a monotonic revision or updatedAt with the completedSessionIDs in localStorage, and in the storage-event handler compare the incoming revision/updatedAt against the local state's revision before applying—if the incoming is older, merge instead of overwrite (e.g., union the incoming next set with the current completedSessionIDs and take the newer updatedAt/revision), and update both localStorage and useCopilotUIStore via useCopilotUIStore.setState only with the reconciled result to avoid clobbering newer data.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In
`@autogpt_platform/frontend/src/app/`(platform)/copilot/useCopilotNotifications.ts:
- Around line 160-163: The current storage-event handler in
useCopilotNotifications.ts blindly applies the incoming snapshot via
useCopilotUIStore.setState({ completedSessionIDs: next }), which allows stale
storage events to overwrite newer local state; fix by adding a simple
reconciliation: persist a monotonic revision or updatedAt with the
completedSessionIDs in localStorage, and in the storage-event handler compare
the incoming revision/updatedAt against the local state's revision before
applying—if the incoming is older, merge instead of overwrite (e.g., union the
incoming next set with the current completedSessionIDs and take the newer
updatedAt/revision), and update both localStorage and useCopilotUIStore via
useCopilotUIStore.setState only with the reconciled result to avoid clobbering
newer data.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 65b0dc68-24d6-4b94-a6a1-fe2d05cb3d8f
📒 Files selected for processing (1)
autogpt_platform/frontend/src/app/(platform)/copilot/useCopilotNotifications.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: types
- GitHub Check: Seer Code Review
- GitHub Check: end-to-end tests
- GitHub Check: Check PR Status
🧰 Additional context used
📓 Path-based instructions (10)
autogpt_platform/frontend/**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
autogpt_platform/frontend/**/*.{ts,tsx,js,jsx}: Use Node.js 21+ with pnpm package manager for frontend development
Always run 'pnpm format' for formatting and linting code in frontend development
autogpt_platform/frontend/**/*.{ts,tsx,js,jsx}: Runpnpm formatto auto-fix formatting issues before completing work
Runpnpm lintto check for lint errors and fix any that appear before completing work
Files:
autogpt_platform/frontend/src/app/(platform)/copilot/useCopilotNotifications.ts
autogpt_platform/frontend/**/*.{tsx,ts}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
autogpt_platform/frontend/**/*.{tsx,ts}: Use function declarations for components and handlers (not arrow functions) in React components
Only use arrow functions for small inline lambdas (map, filter, etc.) in React components
Use PascalCase for component names and camelCase with 'use' prefix for hook names in React
Use Tailwind CSS utilities only for styling in frontend components
Use design system components from 'src/components/' (atoms, molecules, organisms) in frontend development
Never use 'src/components/legacy/' in frontend code
Only use Phosphor Icons (@phosphor-icons/react) for icons in frontend components
Use generated API hooks from '@/app/api/generated/endpoints/' instead of deprecated 'BackendAPI' or 'src/lib/autogpt-server-api/'
Use React Query for server state (via generated hooks) in frontend development
Default to client components ('use client') in Next.js; only use server components for SEO or extreme TTFB needs
Use '' component for rendering errors in frontend UI; use toast notifications for mutation errors; use 'Sentry.captureException()' for manual exceptions
Separate render logic from data/behavior in React components; keep comments minimal (code should be self-documenting)
Files:
autogpt_platform/frontend/src/app/(platform)/copilot/useCopilotNotifications.ts
autogpt_platform/frontend/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
autogpt_platform/frontend/**/*.{ts,tsx}: No barrel files or 'index.ts' re-exports in frontend code
Regenerate API hooks with 'pnpm generate:api' after backend OpenAPI spec changes in frontend developmentRun
pnpm typesto check for type errors and fix any that appear before completing work
Files:
autogpt_platform/frontend/src/app/(platform)/copilot/useCopilotNotifications.ts
autogpt_platform/frontend/**/*.{js,jsx,ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
autogpt_platform/frontend/**/*.{js,jsx,ts,tsx}: Format frontend code usingpnpm format
Never use components fromsrc/components/__legacy__/*
Files:
autogpt_platform/frontend/src/app/(platform)/copilot/useCopilotNotifications.ts
autogpt_platform/frontend/src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
autogpt_platform/frontend/src/**/*.{ts,tsx}: Structure components asComponentName/ComponentName.tsx+useComponentName.ts+helpers.tsand use design system components fromsrc/components/(atoms, molecules, organisms)
Use generated API hooks from@/app/api/__generated__/endpoints/with patternuse{Method}{Version}{OperationName}and regenerate withpnpm generate:api
Use function declarations (not arrow functions) for components and handlers
Separate render logic from business logic with component.tsx + useComponent.ts + helpers.ts structure
Colocate state when possible, avoid creating large components, use sub-components in local/componentsfolder
Avoid large hooks, abstract logic intohelpers.tsfiles when sensible
Use arrow functions only for callbacks, not for component declarations
Avoid comments at all times unless the code is very complex
Do not useuseCallbackoruseMemounless asked to optimize a given function
autogpt_platform/frontend/src/**/*.{ts,tsx}: Use function declarations (not arrow functions) for components and handlers
Use type-safe generated API hooks via Orval + React Query for data fetching
Use React Query for server state management and co-locate UI state in components/hooks
Separate render logic (.tsx) from business logic (use*.tshooks)
Use only shadcn/ui (Radix UI primitives) with Tailwind CSS for UI components
Use Phosphor Icons only for all icon implementations
Use ErrorCard component for render errors, toast for mutations, and Sentry for exceptions
Use design system components fromsrc/components/(atoms, molecules, organisms)
Never usesrc/components/__legacy__/*components
Use generated API hooks from@/app/api/__generated__/endpoints/with patternuse{Method}{Version}{OperationName}
Use Tailwind CSS only for styling with design tokens
Do not useuseCallbackoruseMemounless asked to optimize a specific function
Never type withanyunless a variable/attribute can actually be of any type
Files:
autogpt_platform/frontend/src/app/(platform)/copilot/useCopilotNotifications.ts
autogpt_platform/frontend/**/*.{js,jsx,ts,tsx,css}
📄 CodeRabbit inference engine (AGENTS.md)
Use Tailwind CSS only for styling, use design tokens, and use Phosphor Icons only
Files:
autogpt_platform/frontend/src/app/(platform)/copilot/useCopilotNotifications.ts
autogpt_platform/frontend/src/**/*.ts
📄 CodeRabbit inference engine (AGENTS.md)
Do not type hook returns, let Typescript infer as much as possible
Files:
autogpt_platform/frontend/src/app/(platform)/copilot/useCopilotNotifications.ts
autogpt_platform/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Never type with
any, if no types available useunknown
Files:
autogpt_platform/frontend/src/app/(platform)/copilot/useCopilotNotifications.ts
autogpt_platform/frontend/src/**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (autogpt_platform/frontend/CLAUDE.md)
Fully capitalize acronyms in symbols, e.g.
graphID,useBackendAPI
Files:
autogpt_platform/frontend/src/app/(platform)/copilot/useCopilotNotifications.ts
autogpt_platform/frontend/src/**/use*.ts
📄 CodeRabbit inference engine (autogpt_platform/frontend/CLAUDE.md)
autogpt_platform/frontend/src/**/use*.ts: Extract component logic into custom hooks grouped by concern, with each hook in its own.tsfile
Do not type hook returns; let TypeScript infer types as much as possible
Files:
autogpt_platform/frontend/src/app/(platform)/copilot/useCopilotNotifications.ts
🧠 Learnings (3)
📚 Learning: 2026-02-26T21:29:44.105Z
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: autogpt_platform/frontend/CLAUDE.md:0-0
Timestamp: 2026-02-26T21:29:44.105Z
Learning: Applies to autogpt_platform/frontend/**/*.{ts,tsx} : Run `pnpm types` to check for type errors and fix any that appear before completing work
Applied to files:
autogpt_platform/frontend/src/app/(platform)/copilot/useCopilotNotifications.ts
📚 Learning: 2026-03-05T19:50:36.724Z
Learnt from: Bentlybro
Repo: Significant-Gravitas/AutoGPT PR: 0
File: :0-0
Timestamp: 2026-03-05T19:50:36.724Z
Learning: In `autogpt_platform/frontend/src/app/api/helpers.ts`, the `getPaginationNextPageNumber()` function includes an intentional defensive null check (`if (!pagination) return undefined`) after destructuring `lastPage.data.pagination`. This was proven necessary in production because React Query calls `getNextPageParam` even with error responses (e.g., 401s) that lack the expected pagination structure. Returning `undefined` signals React Query to treat it as "no next page" and stop pagination instead of throwing a TypeError. This is valid and should not be flagged in future reviews.
Applied to files:
autogpt_platform/frontend/src/app/(platform)/copilot/useCopilotNotifications.ts
📚 Learning: 2026-03-11T08:40:53.404Z
Learnt from: kcze
Repo: Significant-Gravitas/AutoGPT PR: 12328
File: autogpt_platform/frontend/src/app/(platform)/copilot/useLoadMoreMessages.ts:49-61
Timestamp: 2026-03-11T08:40:53.404Z
Learning: In `autogpt_platform/frontend/src/app/(platform)/copilot/useLoadMoreMessages.ts`, clearing `olderMessages` (and resetting `oldestSequence`/`hasMore`) when `initialOldestSequence` shifts on the same session is intentional. Pages already fetched were based on a now-stale cursor; retaining them risks sequence gaps or duplicates. `ScrollPreserver` keeps the currently visible viewport intact, so only unvisited older pages are dropped. This is a deliberate safe-refetch design tradeoff.
Applied to files:
autogpt_platform/frontend/src/app/(platform)/copilot/useCopilotNotifications.ts
🔇 Additional comments (3)
autogpt_platform/frontend/src/app/(platform)/copilot/useCopilotNotifications.ts (3)
15-33: Good extraction of browser notification behavior.This keeps notification click-navigation logic centralized and safely degrades when notification construction fails.
53-56: Mount-time title hydration is a solid UX improvement.Using persisted
completedSessionIDson load prevents badge/title desync after refresh.
149-156: Nice hardening for malformed storage payloads.The array guard plus string filtering reduces corruption risk from invalid
localStoragevalues.
…4-autopilot-notifications-follow-up
The code referenced /sounds/notification.mp3 but the file is /notification.wav in the public directory. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
🧹 Nitpick comments (1)
autogpt_platform/frontend/src/app/(platform)/copilot/useCopilotNotifications.ts (1)
46-57: Consider explicit Audio cleanup on unmount.The Audio element is stored in
audioRefbut not explicitly cleaned up. While it will be garbage collected, adding cleanup prevents potential edge cases where audio might continue playing during rapid mount/unmount cycles.♻️ Optional cleanup
useEffect(() => { if (typeof window === "undefined") return; const audio = new Audio(NOTIFICATION_SOUND_PATH); audio.volume = 0.5; audioRef.current = audio; const count = useCopilotUIStore.getState().completedSessionIDs.size; if (count > 0) { document.title = `(${count}) AutoPilot is ready - ${ORIGINAL_TITLE}`; } + + return () => { + audio.pause(); + audio.src = ""; + audioRef.current = null; + }; }, []);🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@autogpt_platform/frontend/src/app/`(platform)/copilot/useCopilotNotifications.ts around lines 46 - 57, The effect in useCopilotNotifications.ts creates an Audio(NOTIFICATION_SOUND_PATH) and assigns it to audioRef.current but never cleans it up; update the useEffect that creates the audio (the function referencing audioRef and NOTIFICATION_SOUND_PATH) to return a cleanup function that, if audioRef.current exists, pauses it, sets currentTime to 0, clears its src (or sets src = ""), and sets audioRef.current = null to release references and prevent audio continuing across unmounts. Ensure the cleanup is safe by checking audioRef.current before operating on it.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In
`@autogpt_platform/frontend/src/app/`(platform)/copilot/useCopilotNotifications.ts:
- Around line 46-57: The effect in useCopilotNotifications.ts creates an
Audio(NOTIFICATION_SOUND_PATH) and assigns it to audioRef.current but never
cleans it up; update the useEffect that creates the audio (the function
referencing audioRef and NOTIFICATION_SOUND_PATH) to return a cleanup function
that, if audioRef.current exists, pauses it, sets currentTime to 0, clears its
src (or sets src = ""), and sets audioRef.current = null to release references
and prevent audio continuing across unmounts. Ensure the cleanup is safe by
checking audioRef.current before operating on it.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 1473dbab-263d-4426-ae51-f8b7c87ef71a
⛔ Files ignored due to path filters (1)
autogpt_platform/frontend/public/notification.wavis excluded by!**/*.wav
📒 Files selected for processing (1)
autogpt_platform/frontend/src/app/(platform)/copilot/useCopilotNotifications.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
- GitHub Check: types
- GitHub Check: Seer Code Review
- GitHub Check: Check PR Status
- GitHub Check: end-to-end tests
- GitHub Check: Analyze (python)
🧰 Additional context used
📓 Path-based instructions (10)
autogpt_platform/frontend/**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
autogpt_platform/frontend/**/*.{ts,tsx,js,jsx}: Use Node.js 21+ with pnpm package manager for frontend development
Always run 'pnpm format' for formatting and linting code in frontend development
autogpt_platform/frontend/**/*.{ts,tsx,js,jsx}: Runpnpm formatto auto-fix formatting issues before completing work
Runpnpm lintto check for lint errors and fix any that appear before completing work
Files:
autogpt_platform/frontend/src/app/(platform)/copilot/useCopilotNotifications.ts
autogpt_platform/frontend/**/*.{tsx,ts}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
autogpt_platform/frontend/**/*.{tsx,ts}: Use function declarations for components and handlers (not arrow functions) in React components
Only use arrow functions for small inline lambdas (map, filter, etc.) in React components
Use PascalCase for component names and camelCase with 'use' prefix for hook names in React
Use Tailwind CSS utilities only for styling in frontend components
Use design system components from 'src/components/' (atoms, molecules, organisms) in frontend development
Never use 'src/components/legacy/' in frontend code
Only use Phosphor Icons (@phosphor-icons/react) for icons in frontend components
Use generated API hooks from '@/app/api/generated/endpoints/' instead of deprecated 'BackendAPI' or 'src/lib/autogpt-server-api/'
Use React Query for server state (via generated hooks) in frontend development
Default to client components ('use client') in Next.js; only use server components for SEO or extreme TTFB needs
Use '' component for rendering errors in frontend UI; use toast notifications for mutation errors; use 'Sentry.captureException()' for manual exceptions
Separate render logic from data/behavior in React components; keep comments minimal (code should be self-documenting)
Files:
autogpt_platform/frontend/src/app/(platform)/copilot/useCopilotNotifications.ts
autogpt_platform/frontend/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
autogpt_platform/frontend/**/*.{ts,tsx}: No barrel files or 'index.ts' re-exports in frontend code
Regenerate API hooks with 'pnpm generate:api' after backend OpenAPI spec changes in frontend developmentRun
pnpm typesto check for type errors and fix any that appear before completing work
Files:
autogpt_platform/frontend/src/app/(platform)/copilot/useCopilotNotifications.ts
autogpt_platform/frontend/**/*.{js,jsx,ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
autogpt_platform/frontend/**/*.{js,jsx,ts,tsx}: Format frontend code usingpnpm format
Never use components fromsrc/components/__legacy__/*
Files:
autogpt_platform/frontend/src/app/(platform)/copilot/useCopilotNotifications.ts
autogpt_platform/frontend/src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
autogpt_platform/frontend/src/**/*.{ts,tsx}: Structure components asComponentName/ComponentName.tsx+useComponentName.ts+helpers.tsand use design system components fromsrc/components/(atoms, molecules, organisms)
Use generated API hooks from@/app/api/__generated__/endpoints/with patternuse{Method}{Version}{OperationName}and regenerate withpnpm generate:api
Use function declarations (not arrow functions) for components and handlers
Separate render logic from business logic with component.tsx + useComponent.ts + helpers.ts structure
Colocate state when possible, avoid creating large components, use sub-components in local/componentsfolder
Avoid large hooks, abstract logic intohelpers.tsfiles when sensible
Use arrow functions only for callbacks, not for component declarations
Avoid comments at all times unless the code is very complex
Do not useuseCallbackoruseMemounless asked to optimize a given function
autogpt_platform/frontend/src/**/*.{ts,tsx}: Use function declarations (not arrow functions) for components and handlers
Use type-safe generated API hooks via Orval + React Query for data fetching
Use React Query for server state management and co-locate UI state in components/hooks
Separate render logic (.tsx) from business logic (use*.tshooks)
Use only shadcn/ui (Radix UI primitives) with Tailwind CSS for UI components
Use Phosphor Icons only for all icon implementations
Use ErrorCard component for render errors, toast for mutations, and Sentry for exceptions
Use design system components fromsrc/components/(atoms, molecules, organisms)
Never usesrc/components/__legacy__/*components
Use generated API hooks from@/app/api/__generated__/endpoints/with patternuse{Method}{Version}{OperationName}
Use Tailwind CSS only for styling with design tokens
Do not useuseCallbackoruseMemounless asked to optimize a specific function
Never type withanyunless a variable/attribute can actually be of any type
Files:
autogpt_platform/frontend/src/app/(platform)/copilot/useCopilotNotifications.ts
autogpt_platform/frontend/**/*.{js,jsx,ts,tsx,css}
📄 CodeRabbit inference engine (AGENTS.md)
Use Tailwind CSS only for styling, use design tokens, and use Phosphor Icons only
Files:
autogpt_platform/frontend/src/app/(platform)/copilot/useCopilotNotifications.ts
autogpt_platform/frontend/src/**/*.ts
📄 CodeRabbit inference engine (AGENTS.md)
Do not type hook returns, let Typescript infer as much as possible
Files:
autogpt_platform/frontend/src/app/(platform)/copilot/useCopilotNotifications.ts
autogpt_platform/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Never type with
any, if no types available useunknown
Files:
autogpt_platform/frontend/src/app/(platform)/copilot/useCopilotNotifications.ts
autogpt_platform/frontend/src/**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (autogpt_platform/frontend/CLAUDE.md)
Fully capitalize acronyms in symbols, e.g.
graphID,useBackendAPI
Files:
autogpt_platform/frontend/src/app/(platform)/copilot/useCopilotNotifications.ts
autogpt_platform/frontend/src/**/use*.ts
📄 CodeRabbit inference engine (autogpt_platform/frontend/CLAUDE.md)
autogpt_platform/frontend/src/**/use*.ts: Extract component logic into custom hooks grouped by concern, with each hook in its own.tsfile
Do not type hook returns; let TypeScript infer types as much as possible
Files:
autogpt_platform/frontend/src/app/(platform)/copilot/useCopilotNotifications.ts
🧠 Learnings (4)
📚 Learning: 2026-02-26T21:29:44.105Z
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: autogpt_platform/frontend/CLAUDE.md:0-0
Timestamp: 2026-02-26T21:29:44.105Z
Learning: Applies to autogpt_platform/frontend/**/*.{ts,tsx} : Run `pnpm types` to check for type errors and fix any that appear before completing work
Applied to files:
autogpt_platform/frontend/src/app/(platform)/copilot/useCopilotNotifications.ts
📚 Learning: 2026-03-05T19:50:36.724Z
Learnt from: Bentlybro
Repo: Significant-Gravitas/AutoGPT PR: 0
File: :0-0
Timestamp: 2026-03-05T19:50:36.724Z
Learning: In `autogpt_platform/frontend/src/app/api/helpers.ts`, the `getPaginationNextPageNumber()` function includes an intentional defensive null check (`if (!pagination) return undefined`) after destructuring `lastPage.data.pagination`. This was proven necessary in production because React Query calls `getNextPageParam` even with error responses (e.g., 401s) that lack the expected pagination structure. Returning `undefined` signals React Query to treat it as "no next page" and stop pagination instead of throwing a TypeError. This is valid and should not be flagged in future reviews.
Applied to files:
autogpt_platform/frontend/src/app/(platform)/copilot/useCopilotNotifications.ts
📚 Learning: 2026-03-11T08:40:53.404Z
Learnt from: kcze
Repo: Significant-Gravitas/AutoGPT PR: 12328
File: autogpt_platform/frontend/src/app/(platform)/copilot/useLoadMoreMessages.ts:49-61
Timestamp: 2026-03-11T08:40:53.404Z
Learning: In `autogpt_platform/frontend/src/app/(platform)/copilot/useLoadMoreMessages.ts`, clearing `olderMessages` (and resetting `oldestSequence`/`hasMore`) when `initialOldestSequence` shifts on the same session is intentional. Pages already fetched were based on a now-stale cursor; retaining them risks sequence gaps or duplicates. `ScrollPreserver` keeps the currently visible viewport intact, so only unvisited older pages are dropped. This is a deliberate safe-refetch design tradeoff.
Applied to files:
autogpt_platform/frontend/src/app/(platform)/copilot/useCopilotNotifications.ts
📚 Learning: 2026-03-10T08:39:13.707Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12356
File: autogpt_platform/backend/backend/copilot/constants.py:9-12
Timestamp: 2026-03-10T08:39:13.707Z
Learning: In Significant-Gravitas/AutoGPT PR `#12356`, the `COPILOT_SYNTHETIC_ID_PREFIX = "copilot-"` check in `create_auto_approval_record` (human_review.py) is intentional and safe. The `graph_exec_id` passed to this function comes from server-side `PendingHumanReview` DB records (not from user input); the API only accepts `node_exec_id` from users. Synthetic `copilot-*` IDs are only ever created server-side in `run_block.py`. The prefix skip avoids a DB lookup for a `AgentGraphExecution` record that legitimately does not exist for CoPilot sessions, while `user_id` scoping is enforced at the auth layer and on the resulting auto-approval record.
Applied to files:
autogpt_platform/frontend/src/app/(platform)/copilot/useCopilotNotifications.ts
🔇 Additional comments (5)
autogpt_platform/frontend/src/app/(platform)/copilot/useCopilotNotifications.ts (5)
1-8: LGTM!The import of
Keyenables the cross-tab sync feature, and the corrected notification sound path aligns with the actual public asset location per the commit message.
10-33: LGTM!The helper cleanly encapsulates browser notification logic with graceful degradation for restricted contexts. The onclick navigation via
pushState+popstatedispatch is appropriate for SPA routing.
59-111: LGTM!The WebSocket handler correctly implements the notification flow: deduplication, UI state update, and conditional sound/browser notification based on user settings and focus state. The "AutoPilot" branding is consistently applied.
113-141: LGTM!Focus tracking correctly resets the document title only when there are no pending completed sessions. Event listener cleanup is properly implemented.
143-171: LGTM!Cross-tab sync correctly validates the storage payload and updates local state without re-persisting (since the storage event originates from another tab's write). The inline comment clarifies the design rationale for treating localStorage as the source of truth.
The code referenced /sounds/notification.mp3 but the file is /notification.mp3 in the public directory. Also added a .gitignore exception for the notification sound since *.mp3 is globally ignored. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The Zustand store called storage.get() during initialization which runs on both server and client, triggering Sentry alerts (BUILDER-7CB, 7CC, 7C7) for expected SSR behavior. Guard with an isClient check so storage.get() is only called on the client, keeping the Sentry alerts in local-storage.ts to catch genuinely unexpected SSR access elsewhere. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@autogpt_platform/frontend/src/app/`(platform)/copilot/store.ts:
- Around line 16-18: The parsed localStorage value is converted to a Set without
validating element types, which can allow non-string entries into
completedSessionIDs; update the JSON parsing branch that creates parsed to
ensure Array.isArray(parsed) and that every element is a string (e.g., filter or
validate using typeof === "string") before constructing and returning new
Set(parsed), and otherwise return an empty Set to guarantee completedSessionIDs
is Set<string>.
- Around line 23-29: persistCompletedSessions currently writes to storage
without checking isClient or handling exceptions; update the function to first
return early if !isClient, then wrap the storage.clean/ storage.set calls for
Key.COPILOT_COMPLETED_SESSIONS in a try/catch and swallow or log errors
(matching the approach used in loadCompletedSessions) so storage failures don't
bubble up and break state mutation callbacks (calls from the store that invoke
persistCompletedSessions). Ensure you reference and use the existing storage API
and Key.COPILOT_COMPLETED_SESSIONS and keep the function signature
persistCompletedSessions(ids: Set<string>) unchanged.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 1fcfd9ae-4268-4b42-be79-b3ed5aec1cdd
⛔ Files ignored due to path filters (1)
autogpt_platform/frontend/public/notification.mp3is excluded by!**/*.mp3
📒 Files selected for processing (3)
.gitignoreautogpt_platform/frontend/src/app/(platform)/copilot/store.tsautogpt_platform/frontend/src/app/(platform)/copilot/useCopilotNotifications.ts
✅ Files skipped from review due to trivial changes (1)
- .gitignore
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
- GitHub Check: check API types
- GitHub Check: Seer Code Review
- GitHub Check: end-to-end tests
- GitHub Check: Check PR Status
- GitHub Check: Analyze (python)
🧰 Additional context used
📓 Path-based instructions (10)
autogpt_platform/frontend/**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
autogpt_platform/frontend/**/*.{ts,tsx,js,jsx}: Use Node.js 21+ with pnpm package manager for frontend development
Always run 'pnpm format' for formatting and linting code in frontend development
autogpt_platform/frontend/**/*.{ts,tsx,js,jsx}: Runpnpm formatto auto-fix formatting issues before completing work
Runpnpm lintto check for lint errors and fix any that appear before completing work
Files:
autogpt_platform/frontend/src/app/(platform)/copilot/useCopilotNotifications.tsautogpt_platform/frontend/src/app/(platform)/copilot/store.ts
autogpt_platform/frontend/**/*.{tsx,ts}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
autogpt_platform/frontend/**/*.{tsx,ts}: Use function declarations for components and handlers (not arrow functions) in React components
Only use arrow functions for small inline lambdas (map, filter, etc.) in React components
Use PascalCase for component names and camelCase with 'use' prefix for hook names in React
Use Tailwind CSS utilities only for styling in frontend components
Use design system components from 'src/components/' (atoms, molecules, organisms) in frontend development
Never use 'src/components/legacy/' in frontend code
Only use Phosphor Icons (@phosphor-icons/react) for icons in frontend components
Use generated API hooks from '@/app/api/generated/endpoints/' instead of deprecated 'BackendAPI' or 'src/lib/autogpt-server-api/'
Use React Query for server state (via generated hooks) in frontend development
Default to client components ('use client') in Next.js; only use server components for SEO or extreme TTFB needs
Use '' component for rendering errors in frontend UI; use toast notifications for mutation errors; use 'Sentry.captureException()' for manual exceptions
Separate render logic from data/behavior in React components; keep comments minimal (code should be self-documenting)
Files:
autogpt_platform/frontend/src/app/(platform)/copilot/useCopilotNotifications.tsautogpt_platform/frontend/src/app/(platform)/copilot/store.ts
autogpt_platform/frontend/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
autogpt_platform/frontend/**/*.{ts,tsx}: No barrel files or 'index.ts' re-exports in frontend code
Regenerate API hooks with 'pnpm generate:api' after backend OpenAPI spec changes in frontend developmentRun
pnpm typesto check for type errors and fix any that appear before completing work
Files:
autogpt_platform/frontend/src/app/(platform)/copilot/useCopilotNotifications.tsautogpt_platform/frontend/src/app/(platform)/copilot/store.ts
autogpt_platform/frontend/**/*.{js,jsx,ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
autogpt_platform/frontend/**/*.{js,jsx,ts,tsx}: Format frontend code usingpnpm format
Never use components fromsrc/components/__legacy__/*
Files:
autogpt_platform/frontend/src/app/(platform)/copilot/useCopilotNotifications.tsautogpt_platform/frontend/src/app/(platform)/copilot/store.ts
autogpt_platform/frontend/src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
autogpt_platform/frontend/src/**/*.{ts,tsx}: Structure components asComponentName/ComponentName.tsx+useComponentName.ts+helpers.tsand use design system components fromsrc/components/(atoms, molecules, organisms)
Use generated API hooks from@/app/api/__generated__/endpoints/with patternuse{Method}{Version}{OperationName}and regenerate withpnpm generate:api
Use function declarations (not arrow functions) for components and handlers
Separate render logic from business logic with component.tsx + useComponent.ts + helpers.ts structure
Colocate state when possible, avoid creating large components, use sub-components in local/componentsfolder
Avoid large hooks, abstract logic intohelpers.tsfiles when sensible
Use arrow functions only for callbacks, not for component declarations
Avoid comments at all times unless the code is very complex
Do not useuseCallbackoruseMemounless asked to optimize a given function
autogpt_platform/frontend/src/**/*.{ts,tsx}: Use function declarations (not arrow functions) for components and handlers
Use type-safe generated API hooks via Orval + React Query for data fetching
Use React Query for server state management and co-locate UI state in components/hooks
Separate render logic (.tsx) from business logic (use*.tshooks)
Use only shadcn/ui (Radix UI primitives) with Tailwind CSS for UI components
Use Phosphor Icons only for all icon implementations
Use ErrorCard component for render errors, toast for mutations, and Sentry for exceptions
Use design system components fromsrc/components/(atoms, molecules, organisms)
Never usesrc/components/__legacy__/*components
Use generated API hooks from@/app/api/__generated__/endpoints/with patternuse{Method}{Version}{OperationName}
Use Tailwind CSS only for styling with design tokens
Do not useuseCallbackoruseMemounless asked to optimize a specific function
Never type withanyunless a variable/attribute can actually be of any type
Files:
autogpt_platform/frontend/src/app/(platform)/copilot/useCopilotNotifications.tsautogpt_platform/frontend/src/app/(platform)/copilot/store.ts
autogpt_platform/frontend/**/*.{js,jsx,ts,tsx,css}
📄 CodeRabbit inference engine (AGENTS.md)
Use Tailwind CSS only for styling, use design tokens, and use Phosphor Icons only
Files:
autogpt_platform/frontend/src/app/(platform)/copilot/useCopilotNotifications.tsautogpt_platform/frontend/src/app/(platform)/copilot/store.ts
autogpt_platform/frontend/src/**/*.ts
📄 CodeRabbit inference engine (AGENTS.md)
Do not type hook returns, let Typescript infer as much as possible
Files:
autogpt_platform/frontend/src/app/(platform)/copilot/useCopilotNotifications.tsautogpt_platform/frontend/src/app/(platform)/copilot/store.ts
autogpt_platform/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Never type with
any, if no types available useunknown
Files:
autogpt_platform/frontend/src/app/(platform)/copilot/useCopilotNotifications.tsautogpt_platform/frontend/src/app/(platform)/copilot/store.ts
autogpt_platform/frontend/src/**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (autogpt_platform/frontend/CLAUDE.md)
Fully capitalize acronyms in symbols, e.g.
graphID,useBackendAPI
Files:
autogpt_platform/frontend/src/app/(platform)/copilot/useCopilotNotifications.tsautogpt_platform/frontend/src/app/(platform)/copilot/store.ts
autogpt_platform/frontend/src/**/use*.ts
📄 CodeRabbit inference engine (autogpt_platform/frontend/CLAUDE.md)
autogpt_platform/frontend/src/**/use*.ts: Extract component logic into custom hooks grouped by concern, with each hook in its own.tsfile
Do not type hook returns; let TypeScript infer types as much as possible
Files:
autogpt_platform/frontend/src/app/(platform)/copilot/useCopilotNotifications.ts
🧠 Learnings (5)
📓 Common learnings
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12356
File: autogpt_platform/backend/backend/copilot/constants.py:9-12
Timestamp: 2026-03-10T08:39:22.025Z
Learning: In Significant-Gravitas/AutoGPT PR `#12356`, the `COPILOT_SYNTHETIC_ID_PREFIX = "copilot-"` check in `create_auto_approval_record` (human_review.py) is intentional and safe. The `graph_exec_id` passed to this function comes from server-side `PendingHumanReview` DB records (not from user input); the API only accepts `node_exec_id` from users. Synthetic `copilot-*` IDs are only ever created server-side in `run_block.py`. The prefix skip avoids a DB lookup for a `AgentGraphExecution` record that legitimately does not exist for CoPilot sessions, while `user_id` scoping is enforced at the auth layer and on the resulting auto-approval record.
📚 Learning: 2026-03-05T19:50:36.724Z
Learnt from: Bentlybro
Repo: Significant-Gravitas/AutoGPT PR: 0
File: :0-0
Timestamp: 2026-03-05T19:50:36.724Z
Learning: In `autogpt_platform/frontend/src/app/api/helpers.ts`, the `getPaginationNextPageNumber()` function includes an intentional defensive null check (`if (!pagination) return undefined`) after destructuring `lastPage.data.pagination`. This was proven necessary in production because React Query calls `getNextPageParam` even with error responses (e.g., 401s) that lack the expected pagination structure. Returning `undefined` signals React Query to treat it as "no next page" and stop pagination instead of throwing a TypeError. This is valid and should not be flagged in future reviews.
Applied to files:
autogpt_platform/frontend/src/app/(platform)/copilot/useCopilotNotifications.ts
📚 Learning: 2026-03-16T17:28:46.349Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12440
File: autogpt_platform/frontend/src/app/(platform)/library/components/LibraryImportWorkflowDialog/useLibraryImportWorkflowDialog.ts:48-51
Timestamp: 2026-03-16T17:28:46.349Z
Learning: In Significant-Gravitas/AutoGPT, orval-generated API hooks (e.g., `usePostV2ImportAWorkflowFromAnotherToolN8nMakeComZapier` in `autogpt_platform/frontend/src/app/(platform)/library/components/LibraryImportWorkflowDialog/useLibraryImportWorkflowDialog.ts`) return `response.data` typed as a union of all possible response schemas (success + all error schemas, e.g. `HTTP401NotAuthenticatedErrorResponse | HTTPValidationError | ImportWorkflowResponse`). A manual `as SpecificType` cast is necessary to access success-only fields (e.g., `data.graph_id`). This is valid when error paths throw before the cast line. Do not flag such casts as unnecessary in future reviews. Note: the hook was previously named `usePostV2ImportACompetitorWorkflowN8nMakeComZapier` before the API path was renamed to avoid "competitor" wording (per PR `#12440` commit 4c91d39f2).
Applied to files:
autogpt_platform/frontend/src/app/(platform)/copilot/useCopilotNotifications.ts
📚 Learning: 2026-03-11T08:40:59.673Z
Learnt from: kcze
Repo: Significant-Gravitas/AutoGPT PR: 12328
File: autogpt_platform/frontend/src/app/(platform)/copilot/useLoadMoreMessages.ts:49-61
Timestamp: 2026-03-11T08:40:59.673Z
Learning: In `autogpt_platform/frontend/src/app/(platform)/copilot/useLoadMoreMessages.ts`, clearing `olderMessages` (and resetting `oldestSequence`/`hasMore`) when `initialOldestSequence` shifts on the same session is intentional. Pages already fetched were based on a now-stale cursor; retaining them risks sequence gaps or duplicates. `ScrollPreserver` keeps the currently visible viewport intact, so only unvisited older pages are dropped. This is a deliberate safe-refetch design tradeoff.
Applied to files:
autogpt_platform/frontend/src/app/(platform)/copilot/useCopilotNotifications.tsautogpt_platform/frontend/src/app/(platform)/copilot/store.ts
📚 Learning: 2026-03-10T08:39:22.025Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12356
File: autogpt_platform/backend/backend/copilot/constants.py:9-12
Timestamp: 2026-03-10T08:39:22.025Z
Learning: In Significant-Gravitas/AutoGPT PR `#12356`, the `COPILOT_SYNTHETIC_ID_PREFIX = "copilot-"` check in `create_auto_approval_record` (human_review.py) is intentional and safe. The `graph_exec_id` passed to this function comes from server-side `PendingHumanReview` DB records (not from user input); the API only accepts `node_exec_id` from users. Synthetic `copilot-*` IDs are only ever created server-side in `run_block.py`. The prefix skip avoids a DB lookup for a `AgentGraphExecution` record that legitimately does not exist for CoPilot sessions, while `user_id` scoping is enforced at the auth layer and on the resulting auto-approval record.
Applied to files:
autogpt_platform/frontend/src/app/(platform)/copilot/useCopilotNotifications.ts
🔇 Additional comments (1)
autogpt_platform/frontend/src/app/(platform)/copilot/useCopilotNotifications.ts (1)
143-171: MobileDrawer clears completed sessions without syncing document.title.The storage event handler (lines 143–171) doesn't fire in the origin tab, so clearing via MobileDrawer leaves the title stale. ChatSidebar mitigates this with manual title updates on navigation, but MobileDrawer has no such sync. The suggested fix—making title reactive to store count—is valid but would also override context-aware behaviors (e.g., focus handlers conditionally reset title). A more targeted fix is to add a title sync effect in MobileDrawer when clearing, or adopt the reactive pattern if simplicity is preferred.
🤖 PR Review — #12428AutoPilot notification follow-ups — Branding, UX, persistence, cross-tab sync improvements. CI: 0 failures | Diff: ~364 lines Review in progress — will post inline findings if any. |
🤖 PR Review — #12428 (Notification Follow-ups)Verdict: ✅ APPROVED UX improvements for AutoPilot notifications. Sound notification, cross-tab sync via localStorage, branding updates. Well-scoped changes across notification components. Findings: No blockers. All CI checks green. |
majdyz
left a comment
There was a problem hiding this comment.
🤖 LGTM — reviewed code, CI green, no blockers found.
majdyz
left a comment
There was a problem hiding this comment.
Review Summary
Well-scoped set of follow-up fixes. The author has been responsive to feedback throughout -- CodeRabbit's Array.isArray guard, the typeof === "string" filter, isClient guard on persistence, and Abhi's dedup suggestions have all been addressed in subsequent commits. The refactoring into helpers.ts with formatNotificationTitle and parseSessionIDs was a good call and eliminated the duplication cleanly.
CI is fully green. No blockers.
What looks good
- Branding rename is complete and consistent across all surfaces (browser notification, document title, dialog copy, banner copy).
parseSessionIDs/formatNotificationTitleextraction intohelpers.tseliminates the duplication that was flagged in review and also fixes the ChatSidebar bug where"AutoGPT"was hardcoded instead of usingORIGINAL_TITLE.- SSR guard via
const isClient = typeof window !== "undefined"at module scope instore.tspreventsstorage.get()during SSR, which should silence BUILDER-7CB/7CC/7C7 Sentry alerts without removing the Sentry reporting for genuinely unexpected SSR access inlocal-storage.ts. - Cross-tab sync design is sound: localStorage as shared source of truth with snapshot adoption (not merge/union) is the correct choice given that both additions and removals need to propagate. The author's reasoning in the thread about why union would break removal semantics is spot-on.
showBrowserNotificationtry-catch is the right simplification over the earlier SW-specific path, since there's no service worker in the codebase.
Minor observations (non-blocking)
-
isClientat module scope is evaluated once at import time. This works correctly for Next.js (SSR runs the module in Node wherewindowis undefined, then the client re-executes). Just noting that this relies on the standard Next.js module evaluation model -- if the codebase ever moves to a streaming SSR setup where modules are shared, this would need revisiting. Not actionable now. -
clearCopilotLocalDatacallsdocument.title = ORIGINAL_TITLEwithout anisClientguard. All the otherstorage.*calls in that function go throughlocal-storage.tswhich has its own SSR guard, butdocument.titlewould throw during SSR. Since this function is only ever called from user-initiated UI actions (settings reset), it's safe in practice. Just flagging for awareness. -
Audio cleanup on unmount. CodeRabbit suggested adding a cleanup return to the audio preload
useEffect(audio.pause(); audio.src = ""; audioRef.current = null;). This is a minor robustness improvement for rapid mount/unmount cycles. Not blocking, but would be a nice-to-have.
LGTM -- no changes needed.
majdyz
left a comment
There was a problem hiding this comment.
Review Summary
Good PR overall — the branding rename, SSR guards, localStorage persistence, and cross-tab sync are well-structured. The extraction of formatNotificationTitle and parseSessionIDs into shared helpers is a nice DRY improvement. The try-catch on new Notification() for service worker contexts is a solid defensive fix.
Issues found
🟠 Should Fix (2):
-
Tailwind class conflict on
Dialog.Footer: PassingclassName="justify-center"toBaseFooterwhich already has a hardcodedjustify-endis unreliable becauseBaseFooteruses raw string concatenation instead ofcn()/tailwind-merge. The winning class depends on CSS cascade order, not HTML attribute order. Fix either by updatingBaseFooterto usecn(), or by usingstyle={{ justifyContent: "center" }}at the call site. -
No unit tests for
formatNotificationTitleandparseSessionIDs: These are pure functions extracted into a sharedhelpers.tsfile. They have clear edge cases (negative/NaN counts, malformed JSON, non-array payloads, arrays with non-string elements) and are trivial to test. A colocatedhelpers.test.tswould prevent future regressions.
🟡 Nice to Have (2):
-
clearCopilotLocalDataaccessesdocument.titlewithoutisClientguard — inconsistent with the SSR hardening applied to all other initializers in the same file. -
remaining = completedSessionIDs.size - 1inChatSidebarcould theoretically go negative in a cross-tab race. Wrapping inMath.max(0, remaining)would be a small safety net.
Testing request
Please share a screenshot or recording showing:
- The dialog buttons are visually centered (proving the Tailwind class conflict doesn't cause issues on your current build)
- Cross-tab sync: clearing a notification in one tab clears the badge in the other
- Notification sound plays correctly from
/notification.mp3
|
When the feedback is addressed, please re-request review so I can take another look. |
…4-autopilot-notifications-follow-up
- Fix BaseFooter to use cn() instead of raw string concatenation so className overrides (like justify-center) properly merge with defaults - Add isClient guard to clearCopilotLocalData's document.title access - Add Math.max(0, ...) guard for remaining count in ChatSidebar - Add unit tests for formatNotificationTitle and parseSessionIDs Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
AutoPilot (copilot) notifications had several follow-up issues after initial implementation: old "Otto" branding, UX quirks, a service-worker crash, notification state that didn't persist or sync across tabs, a broken notification sound, and noisy Sentry alerts from SSR.
Changes 🏗️
BelltoPulse(Phosphor) in the navbar dropdownnew Notification()in try-catch so it degrades gracefully in service worker / PWA contexts instead of throwingTypeError: Illegal constructorcompletedSessionIDsis now stored in localStorage (copilot-completed-sessions) so it survives page refreshes and new tabsstorageevent listener keepscompletedSessionIDsanddocument.titlein sync across all open tabs — clearing a notification in one tab clears it everywhere/sounds/notification.mp3to/notification.mp3and added a.gitignoreexception (root.gitignorehas a blanket*.mp3ignore rule from legacy AutoGPT agent days)storage.get()is never called during SSR, eliminating spurious Sentry alerts (BUILDER-7CB, 7CC, 7C7) while keeping the Sentry reporting inlocal-storage.tsintact for genuinely unexpected SSR accessChecklist 📋
For code changes: