Skip to content

feat(frontend): Show thinking indicator between CoPilot tool calls - #12203

Closed
Otto-AGPT wants to merge 3 commits into
devfrom
otto/secrt-2035-thinking-indicator-between-streams
Closed

feat(frontend): Show thinking indicator between CoPilot tool calls#12203
Otto-AGPT wants to merge 3 commits into
devfrom
otto/secrt-2035-thinking-indicator-between-streams

Conversation

@Otto-AGPT

Copy link
Copy Markdown
Contributor

Requested by @majdyz

When CoPilot executes multiple tool calls in sequence, the UI previously showed no feedback between completed tool calls — users saw a pause with no indication that the LLM was processing. Now the thinking indicator (e.g. "Reasoning...", "On it...") re-appears after each tool call completes while the LLM processes the result.

Changes

  • Detect when the last message part is a completed tool call (ToolUIPart.state === "result") and re-show the shimmer indicator
  • Pick a fresh random thinking phrase for each new "thinking between tools" phase (using a ref to track state transitions, avoiding flicker)
  • Render the indicator after tool call parts within the same assistant message bubble

How it works

The existing showThinking logic only triggered before the first response. A new isThinkingAfterToolCall check looks at the last part of the assistant message — if it's a tool part with state === "result" and the stream is still active, we know the LLM is processing the tool output and show the indicator.

The indicator disappears as soon as new text starts streaming (because the last part is no longer a completed tool call).

Single file change

ChatMessagesContainer.tsx — no backend changes, no new dependencies.

Fixes SECRT-2035

When CoPilot executes multiple tool calls in sequence, the UI now shows
the thinking indicator (e.g. 'Reasoning...', 'On it...') between completed
tool calls while the LLM processes the result. Previously, the indicator
only appeared before the first response.

Detects when the last message part is a completed tool call (state=result)
and re-shows the shimmer indicator with a fresh random phrase.

Fixes SECRT-2035
@Otto-AGPT
Otto-AGPT requested a review from a team as a code owner February 25, 2026 09:54
@Otto-AGPT
Otto-AGPT requested review from Bentlybro and kcze and removed request for a team February 25, 2026 09:54
@github-project-automation github-project-automation Bot moved this to 🆕 Needs initial review in AutoGPT development kanban Feb 25, 2026
@github-actions github-actions Bot added the platform/frontend AutoGPT Platform - Front end label Feb 25, 2026

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.

@github-actions

github-actions Bot commented Feb 25, 2026

Copy link
Copy Markdown
Contributor

🔍 PR Overlap Detection

This check compares your PR against all other open PRs targeting the same branch to detect potential merge conflicts early.

🔴 Merge Conflicts Detected

The following PRs have been tested and will have merge conflicts if merged after this PR. Consider coordinating with the authors.

Summary: 1 conflict(s), 0 medium risk, 0 low risk (out of 1 PRs with file overlap)


Auto-generated on push. Ignores: openapi.json, lock files.

@coderabbitai

coderabbitai Bot commented Feb 25, 2026

Copy link
Copy Markdown
Contributor

Walkthrough

Detects and handle a "thinking after tool call" state inside ChatMessagesContainer by tracking the last assistant/tool output with a ref, updating the thinking phrase on transitions, and extending rendering conditions for the thinking indicator. No public API changes.

Changes

Cohort / File(s) Summary
Thinking-after-tool logic
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsx
Adds useRef tracking (wasThinkingAfterTool) and isThinkingAfterToolCall detection derived from the last assistant/tool output. Extends showThinking and last-message rendering to include thinking-after-tool scenarios, and adds an effect to set thinkingPhrase on entering that state. Minor internal reorganization only; public props unchanged.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • Bentlybro
  • kcze

Poem

🐰 A tool has hummed, the circuit's still,

My little brain sits, quiet, until
A ref remembers where the thought began,
I nudge the phrase, then hop and scan,
Cheers — the chat resumes with a carrot-filled plan! 🥕

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main feature: adding a thinking indicator display between CoPilot tool calls.
Description check ✅ Passed The description is well-related to the changeset, providing clear context about the feature, implementation details, and the specific file being modified.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch otto/secrt-2035-thinking-indicator-between-streams

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

❤️ Share

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

const lastPart = lastMessage.parts[lastMessage.parts.length - 1];
return (
lastPart.type.startsWith("tool-") &&
(lastPart as ToolUIPart).state === "result"

This comment was marked as outdated.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsx (1)

123-129: Pre-existing: component is an arrow function, not a function declaration.

The coding guidelines require function declarations for components. This is pre-existing and out of scope for this PR, but worth noting for a future cleanup.

🤖 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 123 - 129, The component ChatMessagesContainer is currently defined
as an arrow function; update it to a standard function declaration to follow the
project coding guidelines by refactoring the export const ChatMessagesContainer
= (...) => { ... } into export function ChatMessagesContainer(...) { ... }
(preserving the same props type ChatMessagesContainerProps, parameter names
messages/status/error/isLoading/headerSlot, and all existing implementation and
exports).
🤖 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 142-153: The isThinkingAfterToolCall expression uses an IIFE and
checks (lastPart as ToolUIPart).state === "result", which is invalid; change the
check to use the correct state "output-available" and simplify the IIFE into a
plain local variable for readability: extract const lastPart =
lastMessage.parts[lastMessage.parts.length - 1] before the return and compare
(lastPart as ToolUIPart).state === "output-available" inside
isThinkingAfterToolCall; keep the surrounding status and role checks as-is to
preserve behavior.

---

Nitpick comments:
In
`@autogpt_platform/frontend/src/app/`(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsx:
- Around line 123-129: The component ChatMessagesContainer is currently defined
as an arrow function; update it to a standard function declaration to follow the
project coding guidelines by refactoring the export const ChatMessagesContainer
= (...) => { ... } into export function ChatMessagesContainer(...) { ... }
(preserving the same props type ChatMessagesContainerProps, parameter names
messages/status/error/isLoading/headerSlot, and all existing implementation and
exports).

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 2136def and 675218c.

📒 Files selected for processing (1)
  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.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: types
  • 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

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

Files:

  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsx
autogpt_platform/frontend/src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (autogpt_platform/frontend/CLAUDE.md)

autogpt_platform/frontend/src/**/*.{ts,tsx}: Fully capitalize acronyms in symbols, e.g. graphID, useBackendAPI
Use function declarations (not arrow functions) for components and handlers
Separate render logic (.tsx) from business logic (use*.ts hooks)
Use shadcn/ui (Radix UI primitives) with Tailwind CSS styling for UI components
Use Phosphor Icons only for icons
Use ErrorCard for render errors, toast for mutations, and Sentry for exceptions
Use design system components from src/components/ (atoms, molecules, organisms)
Never use src/components/__legacy__/* components
Use generated API hooks from @/app/api/__generated__/endpoints/ with pattern use{Method}{Version}{OperationName}
Use Tailwind CSS only for styling, with design tokens
Do not use useCallback or useMemo unless asked to optimize a given function
Never type with any unless a variable/attribute can ACTUALLY be of any type

autogpt_platform/frontend/src/**/*.{ts,tsx}: Structure components as ComponentName/ComponentName.tsx + useComponentName.ts + helpers.ts and use design system components from src/components/ (atoms, molecules, organisms)
Use generated API hooks from @/app/api/__generated__/endpoints/ with pattern use{Method}{Version}{OperationName} and regenerate with pnpm 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 /components folder
Avoid large hooks, abstract logic into helpers.ts files 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 use useCallback or useMemo unless asked to optimize a given function

Files:

  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsx
autogpt_platform/frontend/src/app/(platform)/**/components/**/*.{ts,tsx}

📄 CodeRabbit inference engine (autogpt_platform/frontend/CLAUDE.md)

Put sub-components in local components/ folder within feature directories

Files:

  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsx
autogpt_platform/frontend/src/**/*.tsx

📄 CodeRabbit inference engine (autogpt_platform/frontend/CLAUDE.md)

Component props should be type Props = { ... } (not exported) unless it needs to be used outside the component

Component props should be 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/frontend/**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

autogpt_platform/frontend/**/*.{js,jsx,ts,tsx}: Format frontend code using pnpm format
Never use components from src/components/__legacy__/*

Files:

  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsx
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/components/ChatMessagesContainer/ChatMessagesContainer.tsx
autogpt_platform/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Never type with any, if no types available use unknown

Files:

  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.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/ChatMessagesContainer/ChatMessagesContainer.tsx
🪛 GitHub Actions: AutoGPT Platform - Frontend CI
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsx

[error] 151-151: Type error: This comparison appears to be unintentional because the types '"input-streaming" | "input-available" | "approval-requested" | "approval-responded" | "output-available" | "output-error" | "output-denied"' and '"result"' have no overlap.


[error] 151-151: Next.js build failed. Command 'pnpm build' exited with code 1 due to TypeScript type incompatibility at the comparison above.

🔇 Additional comments (2)
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsx (2)

160-172: Effect logic for refreshing thinking phrases looks correct.

The two effects have distinct triggers — one for status === "submitted" and one for the rising edge of isThinkingAfterToolCall via the ref guard — so they won't interfere with each other and each picks a fresh random phrase at the right moment.

One minor note: if isThinkingAfterToolCall is fixed (per the build error above), the second effect will correctly fire only when entering the "thinking after tool call" state and not on every render while in that state, thanks to the wasThinkingAfterTool ref.


303-305: Rendering condition correctly extends the thinking indicator for tool-call gaps.

The condition (!messageHasVisibleContent || isThinkingAfterToolCall) ensures the indicator appears both when the assistant message has no visible content yet and after a tool call completes with visible tool results already present. This is the right approach — the indicator will disappear once a new text part starts streaming.

0ubbe and others added 2 commits February 25, 2026 21:52
…cator

Change ToolUIPart.state check from "result" (invalid) to "output-available"
(the actual AI SDK state for a completed tool call). This fixes the build
and makes the thinking-between-tool-calls feature functional.

Also simplifies the IIFE into a plain local variable for readability.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsx (1)

160-160: Remove inline section comments — code is self-documenting here.

isThinkingAfterToolCall and the useEffect dependency on it are self-describing; the comments add no information beyond what the identifiers already convey. Per coding guidelines, comments should be omitted unless the code is genuinely complex.

♻️ Suggested cleanup
-  // Detect when the LLM is thinking after a completed tool call
   const lastPart =
-  // Pick a new phrase when entering "thinking after tool call" state
   useEffect(() => {

Based on learnings: "Applies to autogpt_platform/frontend/**/*.{tsx,ts}: Separate render logic from data/behavior in React components; keep comments minimal (code should be self-documenting)."

Also applies to: 183-184

🤖 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
at line 160, Remove the inline section comment "// Detect when the LLM is
thinking after a completed tool call" and similar self-describing comments
around the isThinkingAfterToolCall variable and the useEffect that depends on it
in ChatMessagesContainer (the comment at the start of the
isThinkingAfterToolCall section and at 183-184); leave the variable name
isThinkingAfterToolCall and the useEffect intact so behavior is unchanged, only
delete the redundant comment to comply with the guideline of omitting
self-documenting comments.
🤖 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/ChatMessagesContainer.tsx:
- Line 160: Remove the inline section comment "// Detect when the LLM is
thinking after a completed tool call" and similar self-describing comments
around the isThinkingAfterToolCall variable and the useEffect that depends on it
in ChatMessagesContainer (the comment at the start of the
isThinkingAfterToolCall section and at 183-184); leave the variable name
isThinkingAfterToolCall and the useEffect intact so behavior is unchanged, only
delete the redundant comment to comply with the guideline of omitting
self-documenting comments.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 592e967 and ab06840.

📒 Files selected for processing (1)
  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.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). (5)
  • GitHub Check: Seer Code Review
  • GitHub Check: types
  • GitHub Check: Analyze (python)
  • 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

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

Files:

  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsx
autogpt_platform/frontend/src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (autogpt_platform/frontend/CLAUDE.md)

autogpt_platform/frontend/src/**/*.{ts,tsx}: Fully capitalize acronyms in symbols, e.g. graphID, useBackendAPI
Use function declarations (not arrow functions) for components and handlers
Separate render logic (.tsx) from business logic (use*.ts hooks)
Use shadcn/ui (Radix UI primitives) with Tailwind CSS styling for UI components
Use Phosphor Icons only for icons
Use ErrorCard for render errors, toast for mutations, and Sentry for exceptions
Use design system components from src/components/ (atoms, molecules, organisms)
Never use src/components/__legacy__/* components
Use generated API hooks from @/app/api/__generated__/endpoints/ with pattern use{Method}{Version}{OperationName}
Use Tailwind CSS only for styling, with design tokens
Do not use useCallback or useMemo unless asked to optimize a given function
Never type with any unless a variable/attribute can ACTUALLY be of any type

autogpt_platform/frontend/src/**/*.{ts,tsx}: Structure components as ComponentName/ComponentName.tsx + useComponentName.ts + helpers.ts and use design system components from src/components/ (atoms, molecules, organisms)
Use generated API hooks from @/app/api/__generated__/endpoints/ with pattern use{Method}{Version}{OperationName} and regenerate with pnpm 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 /components folder
Avoid large hooks, abstract logic into helpers.ts files 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 use useCallback or useMemo unless asked to optimize a given function

Files:

  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsx
autogpt_platform/frontend/src/app/(platform)/**/components/**/*.{ts,tsx}

📄 CodeRabbit inference engine (autogpt_platform/frontend/CLAUDE.md)

Put sub-components in local components/ folder within feature directories

Files:

  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsx
autogpt_platform/frontend/src/**/*.tsx

📄 CodeRabbit inference engine (autogpt_platform/frontend/CLAUDE.md)

Component props should be type Props = { ... } (not exported) unless it needs to be used outside the component

Component props should be 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/frontend/**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

autogpt_platform/frontend/**/*.{js,jsx,ts,tsx}: Format frontend code using pnpm format
Never use components from src/components/__legacy__/*

Files:

  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsx
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/components/ChatMessagesContainer/ChatMessagesContainer.tsx
autogpt_platform/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Never type with any, if no types available use unknown

Files:

  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.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/ChatMessagesContainer/ChatMessagesContainer.tsx
🧠 Learnings (2)
📚 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} : Separate render logic from data/behavior in React components; keep comments minimal (code should be self-documenting)

Applied to files:

  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsx
📚 Learning: 2026-02-04T16:50:33.615Z
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: autogpt_platform/frontend/CLAUDE.md:0-0
Timestamp: 2026-02-04T16:50:33.615Z
Learning: Applies to autogpt_platform/frontend/src/**/*.tsx : Component props should be `type Props = { ... }` (not exported) unless it needs to be used outside the component

Applied to files:

  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsx
🔇 Additional comments (2)
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsx (2)

149-189: New thinking-after-tool-call logic is correct and well-structured.

  • The wasThinkingAfterTool ref correctly gates setThinkingPhrase to fire only on the false→true transition, preventing repeated phrase churn on consecutive re-renders while the tool output remains output-available.
  • isThinkingAfterToolCall correctly requires status === "streaming" + a terminal tool-part state (output-available), and the "result""output-available" fix from the previous review cycle is in place.
  • The two useEffects have non-overlapping triggers (status === "submitted" vs. isThinkingAfterToolCall), so no double-update race exists.

320-326: Render condition correctly gates inline thinking indicator.

(!messageHasVisibleContent || isThinkingAfterToolCall) ensures the shimmer renders inside the existing assistant bubble after tool parts rather than spawning a duplicate bubble (which is handled by the lastMessage?.role !== "assistant" guard at line 331). No issues.

@autogpt-reviewer autogpt-reviewer left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

PR #12203 — feat(frontend): Show thinking indicator between CoPilot tool calls
Author: Otto-AGPT | Requested by: majdyz | Files: ChatMessagesContainer.tsx (+32/-10)

🎯 Verdict: APPROVE

What This PR Does

When CoPilot executes multiple tool calls in sequence, the UI previously showed no feedback between completed tool calls — users saw a "dead pause" with no indication the LLM was processing the tool output. This PR re-shows the thinking indicator ("Reasoning...", "On it...") after each tool call completes while the LLM processes the result. The indicator disappears as soon as new text starts streaming. Single-file change, no backend modifications, no new dependencies. Fixes SECRT-2035.

Specialist Findings

🛡️ Security ✅ — No security concerns. thinkingPhrase renders hardcoded static strings via React JSX (auto-escaped). The as ToolUIPart cast is guarded by the startsWith("tool-") discriminator check. No dangerouslySetInnerHTML, no new external data consumed, no new attack surface. Purely cosmetic UI change.

🏗️ Architecture ✅ — Clean design. useRef(false) for edge detection (wasThinkingAfterTool) is the correct React pattern — avoids unnecessary re-renders that useState would cause. isThinkingAfterToolCall is derived state (not stored), following single-source-of-truth. No new coupling — component already imports ToolUIPart and inspects part.type. Props interface unchanged.
⚠️ Component is growing complex (3 thinking conditions + 2 useEffects for phrase rotation). If a 4th thinking variant arrives, extract to useThinkingState hook.

Performance ✅ — Negligible overhead. ~5 boolean checks + 1 O(1) array index access per render. useState(getRandomPhrase) correctly uses lazy initializer. wasThinkingAfterTool ref prevents render loops — setThinkingPhrase fires exactly once per false→true transition. No risk of oscillation.

🧪 Testing ⚠️ — Zero test coverage on new logic. However, ChatMessagesContainer has zero existing tests, and the entire copilot directory has no test files. Frontend has only 2 unit test files total. Given this near-zero baseline, this is a nice-to-have rather than a blocker. Notable untested edge case: output-error/output-denied tool states don't trigger the indicator (arguably correct UX — errors should surface differently).

📖 Quality ✅ — Readability grade A. Code is clean and focused. as ToolUIPart cast pattern is consistent with lines 248–310 in the same file. Two minor nits: (1) wasThinkingAfterTool ref drops "Call" vs isThinkingAfterToolCall — rename to wasThinkingAfterToolCall for symmetry; (2) two redundant inline comments (lines 167, 186) that project "minimal comments" guidelines would trim.

📦 Product ✅ — Solves the real "dead pause" UX gap. Flicker risk eliminated by ref-based edge detection. Random phrase rotation makes multi-tool sequences feel alive. Indicator placement (after tool parts, within same bubble) provides natural reading flow. Accessible — shimmer text is real text for screen readers.

📬 Discussion ✅ — All CodeRabbit findings addressed. Critical build-breaking bug ("result""output-available") caught by CodeRabbit + CI + Sentry, fixed in commit 592e967. IIFE simplified to plain variable. Only unaddressed item is cosmetic (redundant comments). CI: 17/17 green. Zero human reviewers so far.

🔎 QA ⚠️Feature works correctly in live testing. Thinking indicators confirmed between tool calls with rotating phrases. Initial thinking, phrase rotation, and indicator clearing all work as expected. Tool result cards render correctly.
⚠️ Console warning spam: ThinkingPhrases flip animation produces ~100+ motion.dev warnings per phrase change (animate filter from "blur(NaNpx)", animate rotateX from "NaNdeg"). Pre-existing animation issue, not introduced by this PR, but now triggered more frequently due to additional phrase changes. Does not crash or affect visual behavior.

Evidence:

Blockers

None.

Should Fix (Follow-up OK)

  1. ChatMessagesContainer.tsx:149 — Rename wasThinkingAfterToolwasThinkingAfterToolCall for naming consistency with isThinkingAfterToolCall
  2. ChatMessagesContainer.tsx:167,186 — Remove redundant inline comments per project "minimal comments" convention
  3. ThinkingPhrases component — Fix animation NaN warnings (blur(NaNpx), rotateX(NaNdeg)) in AnimatePresence transitions (pre-existing, not introduced by this PR, but now more visible)
  4. Consider merging the two useEffect hooks for thinkingPhrase into one for clarity

Risk Assessment

Merge risk: LOW | Rollback: EASY (single file, no API changes, no backend changes)

@ntindle Clean, minimal change that solves a real user-facing UX gap. All 8 specialists approve or have non-blocking concerns only. CI green, feature confirmed working in live QA with video evidence. Ship it.

@github-actions github-actions Bot added the conflicts Automatically applied to PRs with merge conflicts label Feb 26, 2026
@github-actions

Copy link
Copy Markdown
Contributor

This pull request has conflicts with the base branch, please resolve those so we can evaluate the pull request.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

conflicts Automatically applied to PRs with merge conflicts platform/frontend AutoGPT Platform - Front end size/m

Projects

Status: ✅ Done
Status: Done

Development

Successfully merging this pull request may close these issues.

3 participants