fix(frontend/copilot): load older chat messages reliably and preserve scrollback across turns - #12792
Conversation
… viewport The IntersectionObserver guard (scrollHeight <= clientHeight) prevented pagination whenever the rendered page collapsed below viewport height (common after reasoning + tool groups fold into CollapsedToolGroup / ReasoningCollapse), leaving users unable to access older history. Remove the guard, cap auto-fill at 3 consecutive non-scrollable rounds, and add a manual "Load older messages" button as the always-available escape hatch. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…6-chat-history-fails-to-load-when-last-response-fits-entirely
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📜 Recent 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). (2)
WalkthroughAdds a manual "Load older messages" button and exports Changes
Sequence Diagram(s)sequenceDiagram
participant Observer as Intersection Observer
participant Sentinel as LoadMoreSentinel
participant Scroll as Scroll Container
participant Loader as onLoadMore Callback
Observer->>Sentinel: sentinel intersects viewport
Sentinel->>Sentinel: captureAndLoad(fromObserver=true)
Sentinel->>Scroll: read scrollHeight & clientHeight (snapshot)
Sentinel->>Loader: call onLoadMore()
Loader->>Scroll: prepend older messages to DOM
Scroll->>Sentinel: useLayoutEffect runs after DOM update
Sentinel->>Sentinel: compare new scrollHeight vs clientHeight
alt scrollHeight > clientHeight
Sentinel->>Sentinel: reset autoFillRoundsRef (allow auto-trigger)
else still non-scrollable
Sentinel->>Sentinel: increment autoFillRoundsRef (backoff)
end
alt autoFillRoundsRef < MAX_AUTO_FILL_ROUNDS
Sentinel->>Observer: keep observer auto-trigger enabled
else
Sentinel->>Observer: stop auto-triggering (manual button only)
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 docstrings
🧪 Generate unit tests (beta)
Warning Review ran into problems🔥 ProblemsTimed out fetching pipeline failures after 30000ms 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 |
🔍 PR Overlap DetectionThis check compares your PR against all other open PRs targeting the same branch to detect potential merge conflicts early. 🔴 Merge Conflicts DetectedThe following PRs have been tested and will have merge conflicts if merged after this PR. Consider coordinating with the authors.
🟢 Low Risk — File Overlap OnlyThese PRs touch the same files but different sections (click to expand)
Summary: 1 conflict(s), 0 medium risk, 2 low risk (out of 3 PRs with file overlap) Auto-generated on push. Ignores: |
There was a problem hiding this comment.
🧹 Nitpick comments (2)
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/__tests__/LoadMoreSentinel.test.tsx (2)
14-17: Redundant cleanup call.Modern
@testing-library/react(v13+) automatically runs cleanup after each test when using Vitest. The explicitcleanup()inafterEachis unnecessary and can be removed.🧹 Proposed cleanup
describe("LoadMoreSentinel", () => { - afterEach(() => { - cleanup(); - }); - it("renders 'Load older messages' button when hasMore is true and not loading", () => {🤖 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/components/ChatMessagesContainer/__tests__/LoadMoreSentinel.test.tsx around lines 14 - 17, Remove the redundant explicit cleanup call in the LoadMoreSentinel test suite: delete the afterEach(() => { cleanup(); }) block in the __tests__/LoadMoreSentinel.test.tsx file since `@testing-library/react` (v13+) with Vitest auto-runs cleanup; leave the describe("LoadMoreSentinel", ...) and tests intact, ensuring no other references to cleanup() remain.
49-61: Test description mentions spinner but doesn't verify it.The test name "hides the button and shows a spinner while loading" promises two assertions, but only the button absence is verified. Consider adding a check for the spinner element to ensure the loading state renders correctly.
🔧 Suggested addition
it("hides the button and shows a spinner while loading", () => { render( <LoadMoreSentinel hasMore={true} isLoading={true} messageCount={5} onLoadMore={vi.fn()} />, ); expect( screen.queryByRole("button", { name: /load older messages/i }), ).toBeNull(); + // Verify spinner is rendered (adjust query based on LoadingSpinner's DOM structure) + expect(screen.getByRole("status")).toBeDefined(); });🤖 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/components/ChatMessagesContainer/__tests__/LoadMoreSentinel.test.tsx around lines 49 - 61, The test for LoadMoreSentinel currently verifies the button is hidden but doesn't assert the spinner is shown; update the test "hides the button and shows a spinner while loading" to also assert the loading indicator is rendered when isLoading={true} by adding an assertion such as checking for a spinner by role or label (e.g., screen.getByRole("status") or screen.getByLabelText(/loading/i) or a known test id like "spinner") after rendering the <LoadMoreSentinel ... isLoading={true} /> so the loading state is fully verified.
🤖 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/components/ChatMessagesContainer/__tests__/LoadMoreSentinel.test.tsx:
- Around line 14-17: Remove the redundant explicit cleanup call in the
LoadMoreSentinel test suite: delete the afterEach(() => { cleanup(); }) block in
the __tests__/LoadMoreSentinel.test.tsx file since `@testing-library/react` (v13+)
with Vitest auto-runs cleanup; leave the describe("LoadMoreSentinel", ...) and
tests intact, ensuring no other references to cleanup() remain.
- Around line 49-61: The test for LoadMoreSentinel currently verifies the button
is hidden but doesn't assert the spinner is shown; update the test "hides the
button and shows a spinner while loading" to also assert the loading indicator
is rendered when isLoading={true} by adding an assertion such as checking for a
spinner by role or label (e.g., screen.getByRole("status") or
screen.getByLabelText(/loading/i) or a known test id like "spinner") after
rendering the <LoadMoreSentinel ... isLoading={true} /> so the loading state is
fully verified.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: eb986964-f9c0-44ab-89ed-18c00c54cefb
📒 Files selected for processing (2)
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsxautogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/__tests__/LoadMoreSentinel.test.tsx
📜 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). (7)
- GitHub Check: integration_test
- GitHub Check: lint
- GitHub Check: check API types
- GitHub Check: Seer Code Review
- GitHub Check: end-to-end tests
- GitHub Check: Analyze (python)
- GitHub Check: Check PR Status
🧰 Additional context used
📓 Path-based instructions (12)
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 developmentFormat frontend code using
pnpm format
Files:
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsxautogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/__tests__/LoadMoreSentinel.test.tsx
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/components/ChatMessagesContainer/ChatMessagesContainer.tsxautogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/__tests__/LoadMoreSentinel.test.tsx
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 development
autogpt_platform/frontend/**/*.{ts,tsx}: Fully capitalize acronyms in symbols, e.g.graphID,useBackendAPI
Use function declarations (not arrow functions) for components and handlers
Nodark:Tailwind classes — the design system handles dark mode
Use Next.js<Link>for internal navigation — never raw<a>tags
Noanytypes unless the value genuinely can be anything
No linter suppressors (//@ts-ignore``,// eslint-disable) — fix the actual issue
Keep files under ~200 lines; extract sub-components or hooks into their own files when a file grows beyond this
Keep render functions and hooks under ~50 lines; extract named helpers or sub-components when they grow longer
Use generated API hooks from `@/app/api/generated/endpoints/` with pattern `use{Method}{Version}{OperationName}` and regenerate with `pnpm generate:api`
Do not use `useCallback` or `useMemo` unless asked to optimise a given function
Separate render logic (`.tsx`) from business logic (`use*.ts` hooks)
Use ErrorCard for render errors, toast for mutations, and Sentry for exceptions in the frontend
Files:
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsxautogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/__tests__/LoadMoreSentinel.test.tsx
autogpt_platform/frontend/src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
autogpt_platform/frontend/src/**/*.{ts,tsx}: Use generated API hooks from@/app/api/__generated__/endpoints/following the patternuse{Method}{Version}{OperationName}, and regenerate withpnpm generate:api
Separate render logic from business logic using component.tsx + useComponent.ts + helpers.ts pattern, colocate state when possible and avoid creating large components, use sub-components in local/componentsfolder
Use function declarations for components and handlers, use arrow functions only for callbacks
Do not useuseCallbackoruseMemounless asked to optimise a given function
Files:
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsxautogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/__tests__/LoadMoreSentinel.test.tsx
autogpt_platform/frontend/**/*.{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/components/ChatMessagesContainer/ChatMessagesContainer.tsxautogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/__tests__/LoadMoreSentinel.test.tsx
autogpt_platform/frontend/src/**/*.tsx
📄 CodeRabbit inference engine (AGENTS.md)
Component props should use
interface Props { ... }(not exported) unless the interface needs to be used outside the component
Files:
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsxautogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/__tests__/LoadMoreSentinel.test.tsx
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/components/ChatMessagesContainer/ChatMessagesContainer.tsxautogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/__tests__/LoadMoreSentinel.test.tsx
autogpt_platform/frontend/src/app/(platform)/**/components/**/*.tsx
📄 CodeRabbit inference engine (autogpt_platform/frontend/AGENTS.md)
Put sub-components in local
components/folder
Files:
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsxautogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/__tests__/LoadMoreSentinel.test.tsx
autogpt_platform/frontend/**/*.tsx
📄 CodeRabbit inference engine (autogpt_platform/frontend/AGENTS.md)
autogpt_platform/frontend/**/*.tsx: Component props should betype Props = { ... }(not exported) unless it needs to be used outside the component
Use design system components fromsrc/components/(atoms, molecules, organisms)
Never usesrc/components/__legacy__/*
Tailwind CSS only for styling, use design tokens, Phosphor Icons only
Files:
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsxautogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/__tests__/LoadMoreSentinel.test.tsx
autogpt_platform/frontend/**/*.{test,spec}.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
autogpt_platform/frontend/**/*.{test,spec}.{ts,tsx}: Use Vitest + RTL + MSW for integration tests as the primary testing approach (~90%, page-level), use Playwright for E2E critical flows, and use Storybook for design system components
Run frontend integration tests withpnpm test:unit(Vitest + RTL + MSW)
Files:
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/__tests__/LoadMoreSentinel.test.tsx
autogpt_platform/frontend/src/app/(platform)/**/__tests__/**/*.test.{ts,tsx}
📄 CodeRabbit inference engine (autogpt_platform/frontend/AGENTS.md)
Write integration tests in
__tests__/next topage.tsxusing Vitest + RTL + MSW for new pages/features
Files:
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/__tests__/LoadMoreSentinel.test.tsx
autogpt_platform/frontend/src/**/__tests__/**/*.test.{ts,tsx}
📄 CodeRabbit inference engine (autogpt_platform/frontend/AGENTS.md)
Use Orval-generated MSW handlers from
@/app/api/__generated__/endpoints/{tag}/{tag}.msw.tsfor API mocking
Files:
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/__tests__/LoadMoreSentinel.test.tsx
🧠 Learnings (28)
📓 Common learnings
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.
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12773
File: autogpt_platform/backend/backend/copilot/pending_messages.py:52-64
Timestamp: 2026-04-14T14:36:22.396Z
Learning: In `autogpt_platform/backend/backend/copilot` (PR `#12773`, commit d7bced0c6): when draining pending messages into `session.messages`, each message's text is sanitized via `strip_user_context_tags` before persistence to prevent user-controlled `<user_context>` injection from bypassing the trusted server-side context prefix. Additionally, if `upsert_chat_session` fails after draining, the drained `PendingMessage` objects are requeued back to Redis to avoid silent message loss. Do NOT flag the drain-then-requeue pattern as redundant — it is the intentional failure-resilience strategy for the pending buffer.
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12445
File: autogpt_platform/backend/backend/copilot/sdk/service.py:1071-1072
Timestamp: 2026-03-17T06:48:26.471Z
Learning: In Significant-Gravitas/AutoGPT (autogpt_platform), the AI SDK enforces `z.strictObject({type, errorText})` on SSE `StreamError` responses, so additional fields like `retryable: bool` cannot be added to `StreamError` or serialized via `to_sse()`. Instead, retry signaling for transient Anthropic API errors is done via the `COPILOT_RETRYABLE_ERROR_PREFIX` constant prepended to persisted session messages (in `ChatMessage.content`). The frontend detects retryable errors by checking `markerType === "retryable_error"` from `parseSpecialMarkers()` — no SSE schema changes and no string matching on error text. This pattern was established in PR `#12445`, commit 64d82797b.
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12445
File: autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatContainer/ChatContainer.tsx:55-67
Timestamp: 2026-03-17T06:18:51.570Z
Learning: In `autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatContainer/ChatContainer.tsx`, an explicit `isBusy` guard on the retry handler (`handleRetry`) is not needed. Once `onSend` is invoked, the chat status immediately transitions to "submitted", which causes the `ErrorCard` (containing the retry button) to unmount before a second click can register, making double-send impossible by design.
📚 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/components/ChatMessagesContainer/ChatMessagesContainer.tsxautogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/__tests__/LoadMoreSentinel.test.tsx
📚 Learning: 2026-03-17T06:18:51.570Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12445
File: autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatContainer/ChatContainer.tsx:55-67
Timestamp: 2026-03-17T06:18:51.570Z
Learning: In `autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatContainer/ChatContainer.tsx`, an explicit `isBusy` guard on the retry handler (`handleRetry`) is not needed. Once `onSend` is invoked, the chat status immediately transitions to "submitted", which causes the `ErrorCard` (containing the retry button) to unmount before a second click can register, making double-send impossible by design.
Applied to files:
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsx
📚 Learning: 2026-04-14T14:36:22.396Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12773
File: autogpt_platform/backend/backend/copilot/pending_messages.py:52-64
Timestamp: 2026-04-14T14:36:22.396Z
Learning: In `autogpt_platform/backend/backend/copilot` (PR `#12773`, commit d7bced0c6): when draining pending messages into `session.messages`, each message's text is sanitized via `strip_user_context_tags` before persistence to prevent user-controlled `<user_context>` injection from bypassing the trusted server-side context prefix. Additionally, if `upsert_chat_session` fails after draining, the drained `PendingMessage` objects are requeued back to Redis to avoid silent message loss. Do NOT flag the drain-then-requeue pattern as redundant — it is the intentional failure-resilience strategy for the pending buffer.
Applied to files:
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsx
📚 Learning: 2026-03-17T06:48:26.471Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12445
File: autogpt_platform/backend/backend/copilot/sdk/service.py:1071-1072
Timestamp: 2026-03-17T06:48:26.471Z
Learning: In Significant-Gravitas/AutoGPT (autogpt_platform), the AI SDK enforces `z.strictObject({type, errorText})` on SSE `StreamError` responses, so additional fields like `retryable: bool` cannot be added to `StreamError` or serialized via `to_sse()`. Instead, retry signaling for transient Anthropic API errors is done via the `COPILOT_RETRYABLE_ERROR_PREFIX` constant prepended to persisted session messages (in `ChatMessage.content`). The frontend detects retryable errors by checking `markerType === "retryable_error"` from `parseSpecialMarkers()` — no SSE schema changes and no string matching on error text. This pattern was established in PR `#12445`, commit 64d82797b.
Applied to files:
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsx
📚 Learning: 2026-04-14T06:39:49.111Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12773
File: autogpt_platform/frontend/src/app/api/openapi.json:12803-12806
Timestamp: 2026-04-14T06:39:49.111Z
Learning: Repo: Significant-Gravitas/AutoGPT — autogpt_platform
Intentional message length caps:
- StreamChatRequest.message maxLength = 64000.
- QueuePendingMessageRequest.message maxLength = 32000 (matches PendingMessage.content).
Rationale: both feed the same LLM context window; pending must not exceed stream, and larger ceilings replace legacy 4000/16000.
Applied to files:
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsx
📚 Learning: 2026-04-08T17:28:40.841Z
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: autogpt_platform/frontend/AGENTS.md:0-0
Timestamp: 2026-04-08T17:28:40.841Z
Learning: Applies to autogpt_platform/frontend/**/*.tsx : Use design system components from `src/components/` (atoms, molecules, organisms)
Applied to files:
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.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 design system components from 'src/components/' (atoms, molecules, organisms) in frontend development
Applied to files:
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsx
📚 Learning: 2026-04-13T13:10:33.180Z
Learnt from: 0ubbe
Repo: Significant-Gravitas/AutoGPT PR: 12764
File: autogpt_platform/frontend/src/app/(platform)/library/components/LibraryAgentList/useLibraryAgentList.ts:264-294
Timestamp: 2026-04-13T13:10:33.180Z
Learning: In `autogpt_platform/frontend/src/app/(platform)/library/components/LibraryAgentList/useLibraryAgentList.ts`, the `consecutiveEmptyPagesRef` and `prevFilteredLengthRef` refs used to track filtered-pagination exhaustion are intentional. The one-render lag in `filteredExhausted` (which reads `consecutiveEmptyPagesRef.current` synchronously) is by design — refs are preferred here to avoid triggering extra re-renders for internal fetch-state bookkeeping. Do not flag this as a stale-ref bug in future reviews.
Applied to files:
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.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/ChatMessagesContainer/ChatMessagesContainer.tsxautogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/__tests__/LoadMoreSentinel.test.tsx
📚 Learning: 2026-03-24T02:05:04.672Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12526
File: autogpt_platform/frontend/src/app/(platform)/copilot/CopilotPage.tsx:0-0
Timestamp: 2026-03-24T02:05:04.672Z
Learning: When gating React component logic on a React Query result (e.g., hooks like `useQuery` / `useGetV2GetCopilotUsage`), prefer destructuring and checking `isSuccess` (or aliasing it to a meaningful boolean like `isSuccess: hasUsage`) instead of relying on `!isLoading`. Reason: `isLoading` can be `false` in error/idle states where `data` may still be `undefined`, while `isSuccess` indicates the query completed successfully and `data` is populated.
Applied to files:
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsxautogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/__tests__/LoadMoreSentinel.test.tsx
📚 Learning: 2026-03-24T02:23:31.305Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12526
File: autogpt_platform/frontend/src/app/(platform)/copilot/components/RateLimitResetDialog/RateLimitResetDialog.tsx:0-0
Timestamp: 2026-03-24T02:23:31.305Z
Learning: In the Copilot platform UI code, follow the established Orval hook `onError` error-handling convention: first explicitly detect/handle `ApiError`, then read `error.response?.detail` (if present) as the primary message; if not available, fall back to `error.message`; and finally fall back to a generic string message. This convention should be used for generated Orval hooks even if the custom Orval mutator already maps details into `ApiError.message`, to keep consistency across hooks/components (e.g., `useCronSchedulerDialog.ts`, `useRunGraph.ts`, and rate-limit/reset flows).
Applied to files:
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsxautogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/__tests__/LoadMoreSentinel.test.tsx
📚 Learning: 2026-03-31T14:04:42.444Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12623
File: autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatInput/ChatInput.tsx:172-177
Timestamp: 2026-03-31T14:04:42.444Z
Learning: In the Copilot frontend components under autogpt_platform/frontend/src/app/(platform)/copilot/, Tailwind dark mode variants (e.g., `dark:*`) are intentional and should be allowed. Do not flag `dark:` utilities in these Copilot UI components as incorrect; they are used to ensure proper contrast and correct behavior in both light and dark themes.
Applied to files:
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsxautogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/__tests__/LoadMoreSentinel.test.tsx
📚 Learning: 2026-04-01T18:54:16.035Z
Learnt from: Bentlybro
Repo: Significant-Gravitas/AutoGPT PR: 12633
File: autogpt_platform/frontend/src/app/(platform)/library/components/AgentFilterMenu/AgentFilterMenu.tsx:3-10
Timestamp: 2026-04-01T18:54:16.035Z
Learning: In the frontend, the legacy Select component at `@/components/__legacy__/ui/select` is an intentional, codebase-wide visual-consistency pattern. During code reviews, do not flag or block PRs merely for continuing to use this legacy Select. If a migration to the newer design-system Select is desired, bundle it into a single dedicated cleanup/migration PR that updates all Select usages together (e.g., avoid piecemeal replacements).
Applied to files:
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsxautogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/__tests__/LoadMoreSentinel.test.tsx
📚 Learning: 2026-04-07T09:24:16.582Z
Learnt from: 0ubbe
Repo: Significant-Gravitas/AutoGPT PR: 12686
File: autogpt_platform/frontend/src/app/(no-navbar)/onboarding/steps/__tests__/PainPointsStep.test.tsx:1-19
Timestamp: 2026-04-07T09:24:16.582Z
Learning: In Significant-Gravitas/AutoGPT’s `autogpt_platform/frontend` (Vite + `vitejs/plugin-react` with the automatic JSX transform), do not flag usages of React types/components (e.g., `React.ReactNode`) in `.ts`/`.tsx` files as missing `React` imports. Since the React namespace is made available by the project’s TS/Vite setup, an explicit `import React from 'react'` or `import type { ReactNode } ...` is not required; only treat it as missing if typechecking (e.g., `pnpm types`) would actually fail.
Applied to files:
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsxautogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/__tests__/LoadMoreSentinel.test.tsx
📚 Learning: 2026-04-02T05:43:49.128Z
Learnt from: 0ubbe
Repo: Significant-Gravitas/AutoGPT PR: 12640
File: autogpt_platform/frontend/src/app/(no-navbar)/onboarding/steps/WelcomeStep.tsx:13-13
Timestamp: 2026-04-02T05:43:49.128Z
Learning: Do not flag `import { Question } from "phosphor-icons/react"` as an invalid import. `Question` is a valid named export from `phosphor-icons/react` (as reflected in the package’s generated `.d.ts` files and re-exports via `dist/index.d.ts`), so it should be treated as a supported named export during code reviews.
Applied to files:
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsxautogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/__tests__/LoadMoreSentinel.test.tsx
📚 Learning: 2026-04-13T13:11:07.445Z
Learnt from: 0ubbe
Repo: Significant-Gravitas/AutoGPT PR: 12764
File: autogpt_platform/frontend/src/app/(platform)/library/components/SitrepItem/SitrepItem.tsx:143-145
Timestamp: 2026-04-13T13:11:07.445Z
Learning: In `autogpt_platform/frontend`, do not flag direct interpolation of `executionID` UUID strings into URL query parameters (e.g., `activeItem=${executionID}` in JSX/Next links). If the value is a UUID string matching `[0-9a-f-]`, it contains no reserved URL characters, so additional `encodeURIComponent` or Next.js object-based `href` encoding is unnecessary. Only treat it as an encoding issue if the query-param value is not guaranteed to be UUID-formatted (i.e., may include characters outside `[0-9a-f-]`).
Applied to files:
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsxautogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/__tests__/LoadMoreSentinel.test.tsx
📚 Learning: 2026-04-08T17:28:40.841Z
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: autogpt_platform/frontend/AGENTS.md:0-0
Timestamp: 2026-04-08T17:28:40.841Z
Learning: Applies to autogpt_platform/frontend/src/app/(platform)/**/__tests__/**/*.test.{ts,tsx} : Write integration tests in `__tests__/` next to `page.tsx` using Vitest + RTL + MSW for new pages/features
Applied to files:
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/__tests__/LoadMoreSentinel.test.tsx
📚 Learning: 2026-04-08T17:28:55.678Z
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: autogpt_platform/frontend/src/tests/AGENTS.md:0-0
Timestamp: 2026-04-08T17:28:55.678Z
Learning: Applies to autogpt_platform/frontend/src/tests/**/__tests__/main.test.tsx : Start integration tests at page level with a `main.test.tsx` file before splitting into smaller test files
Applied to files:
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/__tests__/LoadMoreSentinel.test.tsx
📚 Learning: 2026-04-08T17:27:45.740Z
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-08T17:27:45.740Z
Learning: Applies to autogpt_platform/frontend/**/*.{test,spec}.{ts,tsx} : Use Vitest + RTL + MSW for integration tests as the primary testing approach (~90%, page-level), use Playwright for E2E critical flows, and use Storybook for design system components
Applied to files:
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/__tests__/LoadMoreSentinel.test.tsx
📚 Learning: 2026-04-08T17:27:45.740Z
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-08T17:27:45.740Z
Learning: Applies to autogpt_platform/frontend/**/*.{test,spec}.{ts,tsx} : Run frontend integration tests with `pnpm test:unit` (Vitest + RTL + MSW)
Applied to files:
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/__tests__/LoadMoreSentinel.test.tsx
📚 Learning: 2026-04-08T17:28:55.678Z
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: autogpt_platform/frontend/src/tests/AGENTS.md:0-0
Timestamp: 2026-04-08T17:28:55.678Z
Learning: Applies to autogpt_platform/frontend/src/tests/**/*.test.{ts,tsx} : Place unit tests co-located with the file being tested: `Component.test.tsx` next to `Component.tsx`
Applied to files:
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/__tests__/LoadMoreSentinel.test.tsx
📚 Learning: 2026-04-08T17:28:40.841Z
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: autogpt_platform/frontend/AGENTS.md:0-0
Timestamp: 2026-04-08T17:28:40.841Z
Learning: Applies to autogpt_platform/frontend/src/**/__tests__/**/*.test.{ts,tsx} : Use Orval-generated MSW handlers from `@/app/api/__generated__/endpoints/{tag}/{tag}.msw.ts` for API mocking
Applied to files:
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/__tests__/LoadMoreSentinel.test.tsx
📚 Learning: 2026-04-08T17:28:55.678Z
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: autogpt_platform/frontend/src/tests/AGENTS.md:0-0
Timestamp: 2026-04-08T17:28:55.678Z
Learning: Applies to autogpt_platform/frontend/src/tests/**/__tests__/**/*.test.{ts,tsx} : Place integration tests in a `__tests__` folder next to the component being tested
Applied to files:
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/__tests__/LoadMoreSentinel.test.tsx
📚 Learning: 2026-04-08T17:28:55.678Z
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: autogpt_platform/frontend/src/tests/AGENTS.md:0-0
Timestamp: 2026-04-08T17:28:55.678Z
Learning: Applies to autogpt_platform/frontend/src/tests/src/tests/**/*.spec.ts : Import `test` and `expect` from `./coverage-fixture` instead of `playwright/test` in E2E tests to auto-collect V8 coverage per test for Codecov reporting
Applied to files:
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/__tests__/LoadMoreSentinel.test.tsx
📚 Learning: 2026-04-08T17:28:55.678Z
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: autogpt_platform/frontend/src/tests/AGENTS.md:0-0
Timestamp: 2026-04-08T17:28:55.678Z
Learning: Applies to autogpt_platform/frontend/src/tests/**/__tests__/**/*.test.{ts,tsx} : Use `findBy...` methods in integration tests instead of `getBy...` methods to avoid flaky tests by waiting for elements to appear asynchronously
Applied to files:
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/__tests__/LoadMoreSentinel.test.tsx
📚 Learning: 2026-04-08T17:28:55.678Z
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: autogpt_platform/frontend/src/tests/AGENTS.md:0-0
Timestamp: 2026-04-08T17:28:55.678Z
Learning: Use unit tests for isolated components, pure utility functions, component rendering with various props, component state changes, and custom hooks
Applied to files:
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/__tests__/LoadMoreSentinel.test.tsx
📚 Learning: 2026-04-08T17:28:55.678Z
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: autogpt_platform/frontend/src/tests/AGENTS.md:0-0
Timestamp: 2026-04-08T17:28:55.678Z
Learning: Use integration tests for page-level behavior with mocked API responses, components that fetch data, user interactions triggering API calls, and feature flows within a single page
Applied to files:
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/__tests__/LoadMoreSentinel.test.tsx
🔇 Additional comments (3)
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsx (3)
115-119: Well-designed auto-fill capping mechanism.The ref-based tracking cleanly separates auto-triggered loads from manual button clicks. The
captureAndLoad(fromObserver)pattern elegantly captures scroll metrics while tracking the trigger source. Good use of refs to avoid unnecessary re-renders.Also applies to: 150-166
197-205: Counter management logic is correct.The conditional increment/reset based on
scrollHeight > clientHeightproperly detects when the container becomes scrollable. Resetting to 0 when scrollable allows the observer to resume auto-loading in subsequent sessions where content fits.One edge case to note: if the user manually loads messages that make the container scrollable, the counter won't reset (since
autoTriggeredRefis false). This means the observer stays disabled until the component remounts. This appears intentional per the PR description, but worth documenting if the behavior should differ.
208-226: Button implementation follows design system correctly.Using
Buttonfrom@/components/atoms/Button/Buttonwithvariant="ghost"andsize="small"aligns with the design system guidelines. The conditional rendering logic (isLoading ? spinner : hasMore && button) is clear and handles all states properly.
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## dev #12792 +/- ##
==========================================
+ Coverage 64.64% 64.66% +0.01%
==========================================
Files 1819 1820 +1
Lines 133985 134034 +49
Branches 14428 14451 +23
==========================================
+ Hits 86615 86671 +56
+ Misses 44671 44669 -2
+ Partials 2699 2694 -5
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
…refetches When the session query refetched after a stream completed, the newest page's `oldest_sequence` shifted forward. `useLoadMoreMessages` treated that as a signal to wipe `olderRawMessages` and reset the local cursor to the new initial value. Users who had scrolled back lost their loaded history on every new turn, and the next "Load older messages" click fetched a page that overlapped with AI SDK's retained state in `currentMessages`, producing visible duplicates — the "loop of the same past messages" reported in SECRT-2226. Preserve `olderRawMessages` and the local cursor across same-session refetches. The cursor still points to the oldest message we have explicitly loaded, so the next `loadMore` fetches cleanly before it. The gap between the refetched initial window and the older pages is covered by AI SDK's retained state in `currentMessages`. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
If auto-fill hit the 3-round cap, the counter could only be reset when another auto-triggered load became scrollable — but the observer stops firing at the cap, so auto-fill would never run again. Clicking the manual button successfully made the container scrollable, but the reset was gated on `autoTriggeredRef.current` and skipped, leaving the counter stuck at the cap for the rest of the session. Always reset the counter when the container becomes scrollable. Only increment it when a non-scrollable outcome was itself auto-triggered. Also add a data-testid to the load-more spinner and assert it in the loading-state test (caught by reviewers). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
@coderabbitai re nitpicks on
|
|
Tip For best results, initiate chat on the files or code changes.
✏️ Learnings added
🧠 Learnings used |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsx (1)
134-233: ExtractLoadMoreSentinelinto a local component/hook.It is now exported, directly tested, and carries its own observer/backoff/scroll-preservation state. Keeping that in a ~485-line container makes this file harder to reason about and test than necessary.
As per coding guidelines "Separate render logic from business logic using component.tsx + useComponent.ts + helpers.ts pattern, colocate state when possible and avoid creating large components, use sub-components in local
/componentsfolder" and "Keep files under ~200 lines; extract sub-components or hooks into their own files when a file grows beyond this".🤖 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/components/ChatMessagesContainer/ChatMessagesContainer.tsx around lines 134 - 233, The LoadMoreSentinel component (including captureAndLoad, sentinelRef, scrollSnapshotRef, autoFillRoundsRef, autoTriggeredRef, useEffect/ useLayoutEffect logic and MAX_AUTO_FILL_ROUNDS usage) should be extracted out of the large ChatMessagesContainer file into its own local component/hook pair under the components folder: create a LoadMoreSentinel.tsx that contains the JSX and effects and a useLoadMoreSentinel.ts (or keep helper functions) to encapsulate observer/backoff/scroll-preservation state; ensure it imports useStickToBottomContext and accepts the same props (hasMore, isLoading, messageCount, onLoadMore) and preserve behavior (captureAndLoad semantics, observer rootMargin, and scroll adjustment in useLayoutEffect), update the original ChatMessagesContainer to import and render the new component and run tests to confirm no behavioral changes.
🤖 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/components/ChatMessagesContainer/ChatMessagesContainer.tsx:
- Around line 156-176: Add a same-frame re-entry guard around onLoadMore by
introducing a pendingLoadRef boolean (e.g., const pendingLoadRef =
useRef(false)); update captureAndLoad to return early if pendingLoadRef.current
is true (in addition to existing isLoading checks), and set
pendingLoadRef.current = true immediately before calling
onLoadMoreRef.current(). Then clear pendingLoadRef.current = false when the load
cycle completes (watch isLoading in a useEffect and clear when isLoading becomes
false). Apply the same pending-load guard in the manual load handler referenced
around the 221-225 region so observer and button cannot both trigger a duplicate
load.
---
Nitpick comments:
In
`@autogpt_platform/frontend/src/app/`(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsx:
- Around line 134-233: The LoadMoreSentinel component (including captureAndLoad,
sentinelRef, scrollSnapshotRef, autoFillRoundsRef, autoTriggeredRef, useEffect/
useLayoutEffect logic and MAX_AUTO_FILL_ROUNDS usage) should be extracted out of
the large ChatMessagesContainer file into its own local component/hook pair
under the components folder: create a LoadMoreSentinel.tsx that contains the JSX
and effects and a useLoadMoreSentinel.ts (or keep helper functions) to
encapsulate observer/backoff/scroll-preservation state; ensure it imports
useStickToBottomContext and accepts the same props (hasMore, isLoading,
messageCount, onLoadMore) and preserve behavior (captureAndLoad semantics,
observer rootMargin, and scroll adjustment in useLayoutEffect), update the
original ChatMessagesContainer to import and render the new component and run
tests to confirm no behavioral changes.
🪄 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: abc4da2f-cec5-4a55-a20b-8ae08bad0b70
📒 Files selected for processing (2)
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsxautogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/__tests__/LoadMoreSentinel.test.tsx
✅ Files skipped from review due to trivial changes (1)
- autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/tests/LoadMoreSentinel.test.tsx
📜 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). (2)
- GitHub Check: end-to-end tests
- GitHub Check: Check PR Status
🧰 Additional context used
📓 Path-based instructions (9)
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 developmentFormat frontend code using
pnpm format
Files:
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsx
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/components/ChatMessagesContainer/ChatMessagesContainer.tsx
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 development
autogpt_platform/frontend/**/*.{ts,tsx}: Fully capitalize acronyms in symbols, e.g.graphID,useBackendAPI
Use function declarations (not arrow functions) for components and handlers
Nodark:Tailwind classes — the design system handles dark mode
Use Next.js<Link>for internal navigation — never raw<a>tags
Noanytypes unless the value genuinely can be anything
No linter suppressors (//@ts-ignore``,// eslint-disable) — fix the actual issue
Keep files under ~200 lines; extract sub-components or hooks into their own files when a file grows beyond this
Keep render functions and hooks under ~50 lines; extract named helpers or sub-components when they grow longer
Use generated API hooks from `@/app/api/generated/endpoints/` with pattern `use{Method}{Version}{OperationName}` and regenerate with `pnpm generate:api`
Do not use `useCallback` or `useMemo` unless asked to optimise a given function
Separate render logic (`.tsx`) from business logic (`use*.ts` hooks)
Use ErrorCard for render errors, toast for mutations, and Sentry for exceptions in the frontend
Files:
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsx
autogpt_platform/frontend/src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
autogpt_platform/frontend/src/**/*.{ts,tsx}: Use generated API hooks from@/app/api/__generated__/endpoints/following the patternuse{Method}{Version}{OperationName}, and regenerate withpnpm generate:api
Separate render logic from business logic using component.tsx + useComponent.ts + helpers.ts pattern, colocate state when possible and avoid creating large components, use sub-components in local/componentsfolder
Use function declarations for components and handlers, use arrow functions only for callbacks
Do not useuseCallbackoruseMemounless asked to optimise a given function
Files:
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsx
autogpt_platform/frontend/**/*.{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/components/ChatMessagesContainer/ChatMessagesContainer.tsx
autogpt_platform/frontend/src/**/*.tsx
📄 CodeRabbit inference engine (AGENTS.md)
Component props should use
interface Props { ... }(not exported) unless the interface needs to be used outside the component
Files:
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsx
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/components/ChatMessagesContainer/ChatMessagesContainer.tsx
autogpt_platform/frontend/src/app/(platform)/**/components/**/*.tsx
📄 CodeRabbit inference engine (autogpt_platform/frontend/AGENTS.md)
Put sub-components in local
components/folder
Files:
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsx
autogpt_platform/frontend/**/*.tsx
📄 CodeRabbit inference engine (autogpt_platform/frontend/AGENTS.md)
autogpt_platform/frontend/**/*.tsx: Component props should betype Props = { ... }(not exported) unless it needs to be used outside the component
Use design system components fromsrc/components/(atoms, molecules, organisms)
Never usesrc/components/__legacy__/*
Tailwind CSS only for styling, use design tokens, Phosphor Icons only
Files:
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsx
🧠 Learnings (21)
📓 Common learnings
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.
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12773
File: autogpt_platform/backend/backend/copilot/pending_messages.py:52-64
Timestamp: 2026-04-14T14:36:22.396Z
Learning: In `autogpt_platform/backend/backend/copilot` (PR `#12773`, commit d7bced0c6): when draining pending messages into `session.messages`, each message's text is sanitized via `strip_user_context_tags` before persistence to prevent user-controlled `<user_context>` injection from bypassing the trusted server-side context prefix. Additionally, if `upsert_chat_session` fails after draining, the drained `PendingMessage` objects are requeued back to Redis to avoid silent message loss. Do NOT flag the drain-then-requeue pattern as redundant — it is the intentional failure-resilience strategy for the pending buffer.
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12445
File: autogpt_platform/backend/backend/copilot/sdk/service.py:1071-1072
Timestamp: 2026-03-17T06:48:26.471Z
Learning: In Significant-Gravitas/AutoGPT (autogpt_platform), the AI SDK enforces `z.strictObject({type, errorText})` on SSE `StreamError` responses, so additional fields like `retryable: bool` cannot be added to `StreamError` or serialized via `to_sse()`. Instead, retry signaling for transient Anthropic API errors is done via the `COPILOT_RETRYABLE_ERROR_PREFIX` constant prepended to persisted session messages (in `ChatMessage.content`). The frontend detects retryable errors by checking `markerType === "retryable_error"` from `parseSpecialMarkers()` — no SSE schema changes and no string matching on error text. This pattern was established in PR `#12445`, commit 64d82797b.
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12445
File: autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatContainer/ChatContainer.tsx:55-67
Timestamp: 2026-03-17T06:18:51.570Z
Learning: In `autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatContainer/ChatContainer.tsx`, an explicit `isBusy` guard on the retry handler (`handleRetry`) is not needed. Once `onSend` is invoked, the chat status immediately transitions to "submitted", which causes the `ErrorCard` (containing the retry button) to unmount before a second click can register, making double-send impossible by design.
📚 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/components/ChatMessagesContainer/ChatMessagesContainer.tsx
📚 Learning: 2026-03-17T06:18:51.570Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12445
File: autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatContainer/ChatContainer.tsx:55-67
Timestamp: 2026-03-17T06:18:51.570Z
Learning: In `autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatContainer/ChatContainer.tsx`, an explicit `isBusy` guard on the retry handler (`handleRetry`) is not needed. Once `onSend` is invoked, the chat status immediately transitions to "submitted", which causes the `ErrorCard` (containing the retry button) to unmount before a second click can register, making double-send impossible by design.
Applied to files:
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsx
📚 Learning: 2026-04-14T14:36:22.396Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12773
File: autogpt_platform/backend/backend/copilot/pending_messages.py:52-64
Timestamp: 2026-04-14T14:36:22.396Z
Learning: In `autogpt_platform/backend/backend/copilot` (PR `#12773`, commit d7bced0c6): when draining pending messages into `session.messages`, each message's text is sanitized via `strip_user_context_tags` before persistence to prevent user-controlled `<user_context>` injection from bypassing the trusted server-side context prefix. Additionally, if `upsert_chat_session` fails after draining, the drained `PendingMessage` objects are requeued back to Redis to avoid silent message loss. Do NOT flag the drain-then-requeue pattern as redundant — it is the intentional failure-resilience strategy for the pending buffer.
Applied to files:
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsx
📚 Learning: 2026-03-17T06:48:26.471Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12445
File: autogpt_platform/backend/backend/copilot/sdk/service.py:1071-1072
Timestamp: 2026-03-17T06:48:26.471Z
Learning: In Significant-Gravitas/AutoGPT (autogpt_platform), the AI SDK enforces `z.strictObject({type, errorText})` on SSE `StreamError` responses, so additional fields like `retryable: bool` cannot be added to `StreamError` or serialized via `to_sse()`. Instead, retry signaling for transient Anthropic API errors is done via the `COPILOT_RETRYABLE_ERROR_PREFIX` constant prepended to persisted session messages (in `ChatMessage.content`). The frontend detects retryable errors by checking `markerType === "retryable_error"` from `parseSpecialMarkers()` — no SSE schema changes and no string matching on error text. This pattern was established in PR `#12445`, commit 64d82797b.
Applied to files:
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsx
📚 Learning: 2026-04-14T06:39:49.111Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12773
File: autogpt_platform/frontend/src/app/api/openapi.json:12803-12806
Timestamp: 2026-04-14T06:39:49.111Z
Learning: Repo: Significant-Gravitas/AutoGPT — autogpt_platform
Intentional message length caps:
- StreamChatRequest.message maxLength = 64000.
- QueuePendingMessageRequest.message maxLength = 32000 (matches PendingMessage.content).
Rationale: both feed the same LLM context window; pending must not exceed stream, and larger ceilings replace legacy 4000/16000.
Applied to files:
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsx
📚 Learning: 2026-04-13T13:10:33.180Z
Learnt from: 0ubbe
Repo: Significant-Gravitas/AutoGPT PR: 12764
File: autogpt_platform/frontend/src/app/(platform)/library/components/LibraryAgentList/useLibraryAgentList.ts:264-294
Timestamp: 2026-04-13T13:10:33.180Z
Learning: In `autogpt_platform/frontend/src/app/(platform)/library/components/LibraryAgentList/useLibraryAgentList.ts`, the `consecutiveEmptyPagesRef` and `prevFilteredLengthRef` refs used to track filtered-pagination exhaustion are intentional. The one-render lag in `filteredExhausted` (which reads `consecutiveEmptyPagesRef.current` synchronously) is by design — refs are preferred here to avoid triggering extra re-renders for internal fetch-state bookkeeping. Do not flag this as a stale-ref bug in future reviews.
Applied to files:
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsx
📚 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/components/ChatMessagesContainer/ChatMessagesContainer.tsx
📚 Learning: 2026-03-19T12:07:49.237Z
Learnt from: 0ubbe
Repo: Significant-Gravitas/AutoGPT PR: 12462
File: autogpt_platform/frontend/src/app/(platform)/marketplace/components/AgentImages/AgentImage.tsx:17-21
Timestamp: 2026-03-19T12:07:49.237Z
Learning: In `autogpt_platform/frontend/src/app/(platform)/marketplace/components/AgentImages/AgentImage.tsx`, the `images` array passed to `AgentImages` is static per agent detail page and does not change after mount. Therefore, index-based keying of `loadedThumbs` (a `Set<number>`) is sufficient and will not produce stale entries. Do not flag this as a potential stale-state issue due to index reuse.
Applied to files:
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsx
📚 Learning: 2026-04-15T10:17:08.698Z
Learnt from: kcze
Repo: Significant-Gravitas/AutoGPT PR: 0
File: :0-0
Timestamp: 2026-04-15T10:17:08.698Z
Learning: In `Significant-Gravitas/AutoGPT` (`autogpt_platform/frontend`), `vitest.config.mts` does NOT set `globals: true`, and `src/tests/integrations/vitest.setup.tsx` does NOT register the `testing-library/react` auto-cleanup hook. Therefore, integration test files (e.g., under `__tests__/`) MUST include an explicit `afterEach(cleanup)` call from `testing-library/react` to reset the DOM between tests — without it, tests fail with "multiple elements found" errors from the prior test's DOM. Do NOT flag `afterEach(cleanup)` as redundant in this codebase.
Applied to files:
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsx
📚 Learning: 2026-04-08T17:28:40.841Z
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: autogpt_platform/frontend/AGENTS.md:0-0
Timestamp: 2026-04-08T17:28:40.841Z
Learning: Applies to autogpt_platform/frontend/**/*.{ts,tsx} : No linter suppressors (`// ts-ignore`, `// eslint-disable`) — fix the actual issue
Applied to files:
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsx
📚 Learning: 2026-04-08T17:28:40.841Z
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: autogpt_platform/frontend/AGENTS.md:0-0
Timestamp: 2026-04-08T17:28:40.841Z
Learning: Applies to autogpt_platform/frontend/**/*.tsx : Use design system components from `src/components/` (atoms, molecules, organisms)
Applied to files:
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.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 design system components from 'src/components/' (atoms, molecules, organisms) in frontend development
Applied to files:
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.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/ChatMessagesContainer/ChatMessagesContainer.tsx
📚 Learning: 2026-03-24T02:05:04.672Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12526
File: autogpt_platform/frontend/src/app/(platform)/copilot/CopilotPage.tsx:0-0
Timestamp: 2026-03-24T02:05:04.672Z
Learning: When gating React component logic on a React Query result (e.g., hooks like `useQuery` / `useGetV2GetCopilotUsage`), prefer destructuring and checking `isSuccess` (or aliasing it to a meaningful boolean like `isSuccess: hasUsage`) instead of relying on `!isLoading`. Reason: `isLoading` can be `false` in error/idle states where `data` may still be `undefined`, while `isSuccess` indicates the query completed successfully and `data` is populated.
Applied to files:
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsx
📚 Learning: 2026-03-24T02:23:31.305Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12526
File: autogpt_platform/frontend/src/app/(platform)/copilot/components/RateLimitResetDialog/RateLimitResetDialog.tsx:0-0
Timestamp: 2026-03-24T02:23:31.305Z
Learning: In the Copilot platform UI code, follow the established Orval hook `onError` error-handling convention: first explicitly detect/handle `ApiError`, then read `error.response?.detail` (if present) as the primary message; if not available, fall back to `error.message`; and finally fall back to a generic string message. This convention should be used for generated Orval hooks even if the custom Orval mutator already maps details into `ApiError.message`, to keep consistency across hooks/components (e.g., `useCronSchedulerDialog.ts`, `useRunGraph.ts`, and rate-limit/reset flows).
Applied to files:
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsx
📚 Learning: 2026-03-31T14:04:42.444Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12623
File: autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatInput/ChatInput.tsx:172-177
Timestamp: 2026-03-31T14:04:42.444Z
Learning: In the Copilot frontend components under autogpt_platform/frontend/src/app/(platform)/copilot/, Tailwind dark mode variants (e.g., `dark:*`) are intentional and should be allowed. Do not flag `dark:` utilities in these Copilot UI components as incorrect; they are used to ensure proper contrast and correct behavior in both light and dark themes.
Applied to files:
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsx
📚 Learning: 2026-04-01T18:54:16.035Z
Learnt from: Bentlybro
Repo: Significant-Gravitas/AutoGPT PR: 12633
File: autogpt_platform/frontend/src/app/(platform)/library/components/AgentFilterMenu/AgentFilterMenu.tsx:3-10
Timestamp: 2026-04-01T18:54:16.035Z
Learning: In the frontend, the legacy Select component at `@/components/__legacy__/ui/select` is an intentional, codebase-wide visual-consistency pattern. During code reviews, do not flag or block PRs merely for continuing to use this legacy Select. If a migration to the newer design-system Select is desired, bundle it into a single dedicated cleanup/migration PR that updates all Select usages together (e.g., avoid piecemeal replacements).
Applied to files:
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsx
📚 Learning: 2026-04-07T09:24:16.582Z
Learnt from: 0ubbe
Repo: Significant-Gravitas/AutoGPT PR: 12686
File: autogpt_platform/frontend/src/app/(no-navbar)/onboarding/steps/__tests__/PainPointsStep.test.tsx:1-19
Timestamp: 2026-04-07T09:24:16.582Z
Learning: In Significant-Gravitas/AutoGPT’s `autogpt_platform/frontend` (Vite + `vitejs/plugin-react` with the automatic JSX transform), do not flag usages of React types/components (e.g., `React.ReactNode`) in `.ts`/`.tsx` files as missing `React` imports. Since the React namespace is made available by the project’s TS/Vite setup, an explicit `import React from 'react'` or `import type { ReactNode } ...` is not required; only treat it as missing if typechecking (e.g., `pnpm types`) would actually fail.
Applied to files:
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsx
📚 Learning: 2026-04-02T05:43:49.128Z
Learnt from: 0ubbe
Repo: Significant-Gravitas/AutoGPT PR: 12640
File: autogpt_platform/frontend/src/app/(no-navbar)/onboarding/steps/WelcomeStep.tsx:13-13
Timestamp: 2026-04-02T05:43:49.128Z
Learning: Do not flag `import { Question } from "phosphor-icons/react"` as an invalid import. `Question` is a valid named export from `phosphor-icons/react` (as reflected in the package’s generated `.d.ts` files and re-exports via `dist/index.d.ts`), so it should be treated as a supported named export during code reviews.
Applied to files:
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsx
📚 Learning: 2026-04-13T13:11:07.445Z
Learnt from: 0ubbe
Repo: Significant-Gravitas/AutoGPT PR: 12764
File: autogpt_platform/frontend/src/app/(platform)/library/components/SitrepItem/SitrepItem.tsx:143-145
Timestamp: 2026-04-13T13:11:07.445Z
Learning: In `autogpt_platform/frontend`, do not flag direct interpolation of `executionID` UUID strings into URL query parameters (e.g., `activeItem=${executionID}` in JSX/Next links). If the value is a UUID string matching `[0-9a-f-]`, it contains no reserved URL characters, so additional `encodeURIComponent` or Next.js object-based `href` encoding is unnecessary. Only treat it as an encoding issue if the query-param value is not guaranteed to be UUID-formatted (i.e., may include characters outside `[0-9a-f-]`).
Applied to files:
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsx
…fect paths Mock IntersectionObserver and useStickToBottomContext's scrollRef so the observer callback, scroll-restore math, auto-fill round counter and cap, and the counter-reset-on-scrollable path are all exercised by tests. Brings codecov patch coverage on ChatMessagesContainer.tsx over the 80% threshold on the lines changed in this PR. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ntry The parent's isLoading flag lags the trigger by a render, so the observer (or manual button, or both) could fire captureAndLoad more than once in the same frame. That issued duplicate page requests for the same cursor and overwrote the preserved scroll snapshot. Add a ref-based pending-load latch set synchronously in captureAndLoad and cleared via useEffect when isLoading transitions to false. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Issues attributed to commits in this pull requestThis pull request was merged and Sentry observed the following issues:
|
Why / What / How
Fixes two SECRT-2226 bugs in copilot chat pagination.
Bug 1 — can't load older messages when the newest page fits on screen. The
IntersectionObserverinLoadMoreSentinelbailed whenscrollHeight <= clientHeight, which happens routinely once reasoning + tool groups collapse. With no scrollbar and no button, users were stuck. Fix: remove the guard, cap auto-fill at 3 non-scrollable rounds (keeps the original anti-loop intent), and add a manual "Load older messages" button as the always-available escape hatch.Bug 2 — older loaded pages vanish after a new turn, then reloading them produces duplicates. After each stream
useCopilotStreaminvalidates the session query; the refetch returns a shiftedoldest_sequence, whichuseLoadMoreMessagesused as a signal to wipeolderRawMessagesand reset the local cursor. Scroll-back history was lost on every turn, and the next load fetched a page that overlapped with AI SDK's retainedcurrentMessages— the "loops" users reported. Fix: once any older page is loaded, preserveolderRawMessagesand the local cursor across same-session refetches. Only reset on session change. The gap between the new initial window and older pages is covered by AI SDK's retained state.Changes 🏗️
ChatMessagesContainer.tsx: drop the scrollability guard; addMAX_AUTO_FILL_ROUNDS = 3counter; add "Load older messages" button (ghost/small); distinguish observer-triggered vs. button-triggered loads so the button bypasses the cap; exportLoadMoreSentinelfor testing.useLoadMoreMessages.ts: remove the wipe-and-reset branch oninitialOldestSequencechange; preserve local state mid-session; still mirror parent's cursor while no older page is loaded.__tests__/LoadMoreSentinel.test.tsx.No backend changes.
Checklist 📋
For code changes:
has_more_messages=falsehides the button;isLoadingMore=trueshows spinner insteadlimit=5: before fix older page vanished and next load duplicated AI SDK messages; after fix older page stays and next load fetches cleanly further backpnpm format,pnpm lint,pnpm types,pnpm test:unitall pass (1208/1208)For configuration changes:
.env.defaultis updated or already compatible with my changesdocker-compose.ymlis updated or already compatible with my changes