Skip to content

feat(copilot): collapse repeated tool calls and fix stream stuck on completion - #12282

Merged
0ubbe merged 11 commits into
devfrom
lluisagusti/secrt-2024-collapse-repeated-block-executions-into-grouped-summary-rows
Mar 6, 2026
Merged

feat(copilot): collapse repeated tool calls and fix stream stuck on completion#12282
0ubbe merged 11 commits into
devfrom
lluisagusti/secrt-2024-collapse-repeated-block-executions-into-grouped-summary-rows

Conversation

@0ubbe

@0ubbe 0ubbe commented Mar 4, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Frontend: Group consecutive completed generic tool parts into collapsible summary rows with a "Reasoning" collapse for finalized messages. Merge consecutive assistant messages on hydration to avoid split bubbles. Extract GenericTool helpers. Add reconnectExhausted state and a brief delay before refetching session to reduce stale active_stream reconnect cycles.
  • Backend: Make transcript upload fire-and-forget instead of blocking the generator exit. The 30s upload timeout in _try_upload_transcript was delaying mark_session_completed(), keeping the SSE stream alive with only heartbeats after the LLM had finished — causing the UI to stay stuck in "streaming" state.

Test plan

  • Send a message in Copilot that triggers multiple tool calls — verify they collapse into a grouped summary row once completed
  • Verify the final text response appears below the collapsed reasoning section
  • Confirm the stream properly closes after the agent finishes (no stuck "Stop" button)
  • Refresh mid-stream and verify reconnection works correctly
  • Click Stop during streaming — verify the UI becomes responsive immediately

🤖 Generated with Claude Code

0ubbe and others added 2 commits March 4, 2026 20:49
…vote) with Langfuse feedback

Add copy, upvote, and downvote action buttons to assistant messages in the
CoPilot chat. Feedback is submitted to the backend Langfuse integration for
observability. Downvote opens a modal for optional detailed feedback.

- AssistantMessageActions: renders copy/upvote/downvote with hover reveal
- FeedbackModal: dialog for optional downvote comment (max 2000 chars)
- useMessageFeedback: manages feedback state and backend submission
- Actions hidden during streaming, visible on hover or after selection

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

Frontend:
- Group consecutive completed generic tool parts into collapsible summaries
- Split finalized assistant messages into reasoning (tools) and response sections
- Merge consecutive assistant messages on hydration to avoid split bubbles
- Extract GenericTool helpers to dedicated file
- Add reconnectExhausted state to unblock UI when all reconnect attempts fail
- Add 500ms delay before refetching session to reduce stale active_stream races

Backend:
- Make transcript upload fire-and-forget instead of blocking the generator exit
  The 30s upload timeout was delaying mark_session_completed(), keeping the SSE
  stream alive with only heartbeats after the LLM had finished

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@0ubbe
0ubbe requested a review from a team as a code owner March 4, 2026 15:12
@0ubbe
0ubbe requested review from Pwuts and majdyz and removed request for a team March 4, 2026 15:12
@github-project-automation github-project-automation Bot moved this to 🆕 Needs initial review in AutoGPT development kanban Mar 4, 2026
@github-actions github-actions Bot added the conflicts Automatically applied to PRs with merge conflicts label Mar 4, 2026
@github-actions

github-actions Bot commented Mar 4, 2026

Copy link
Copy Markdown
Contributor

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

@github-actions github-actions Bot added platform/frontend AutoGPT Platform - Front end platform/backend AutoGPT Platform - Back end and removed conflicts Automatically applied to PRs with merge conflicts labels Mar 4, 2026
@coderabbitai

This comment was marked as outdated.

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

github-actions Bot commented Mar 4, 2026

Copy link
Copy Markdown
Contributor

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

…k-executions-into-grouped-summary-rows

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@github-actions github-actions Bot removed the conflicts Automatically applied to PRs with merge conflicts label Mar 4, 2026
@github-actions

github-actions Bot commented Mar 4, 2026

Copy link
Copy Markdown
Contributor

Conflicts have been resolved! 🎉 A maintainer will review the pull request shortly.

@github-actions

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: 6

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

40-40: Prefer design-token color utilities over hardcoded slate shades.

Using text-slate-600 / text-slate-400 makes theming less consistent with the rest of the design system. Prefer semantic token classes (for example text-muted-foreground).

As per coding guidelines: "Use Tailwind CSS only for styling, use design tokens, and use Phosphor Icons only."

Also applies to: 52-52

🤖 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/components/FeedbackModal.tsx
at line 40, In FeedbackModal.tsx replace hardcoded slate classes with
design-token color utilities: locate the <p> elements in the FeedbackModal
component that currently use "text-slate-600" and "text-slate-400" (and any
similar slate-* uses) and swap them for the semantic token classes used across
the app (for example "text-muted-foreground" or the appropriate token for
secondary text) by updating their className props; ensure you only change the
color utility while preserving other classes on those elements so theming
remains consistent with the design system.
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/useMessageFeedback.ts (1)

22-37: Prefer generated API hook for feedback mutation instead of raw fetch.

Using the generated endpoint hook here will keep auth/error handling and typing consistent with the rest of Copilot API calls.

As per coding guidelines: "Use generated API hooks from @/app/api/__generated__/endpoints/ with pattern use{Method}{Version}{OperationName}."

🤖 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/useMessageFeedback.ts
around lines 22 - 37, The raw fetch call in useMessageFeedback (sending to
/api/chat/sessions/{sessionID}/feedback with args.sessionID, args.messageID,
args.scoreName, args.scoreValue, args.comment) should be replaced with the
generated API mutation hook from "@/app/api/__generated__/endpoints/" (the hook
following the pattern use{Method}{Version}{OperationName}, e.g., the POST hook
for /chat/sessions/{sessionID}/feedback); import that hook, call it instead of
fetch, and pass the sessionID and payload (message_id, score_name, score_value,
comment) so you get the built-in auth, error handling and typings consistent
with other Copilot API calls.
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsx (1)

27-152: Extract segmentation/splitting logic to helpers.ts to keep the component lean.

isCompletedToolPart, buildRenderSegments, splitReasoningAndResponse, and renderSegments are substantial business/render-prep logic in the component file. Moving them to ChatMessagesContainer/helpers.ts will improve readability and testability.

As per coding guidelines: "Separate render logic from business logic with component.tsx + useComponent.ts + helpers.ts structure" and "Structure components as ComponentName/ComponentName.tsx + useComponentName.ts + helpers.ts."

🤖 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 27 - 152, Move the non-UI logic from the component into a new
helper module: create ChatMessagesContainer/helpers.ts and export
isCompletedToolPart, buildRenderSegments, splitReasoningAndResponse, and
renderSegments from it; update ChatMessagesContainer.tsx to import those
functions instead of defining them inline (ensure renderSegments still returns
React.ReactNode[] and that types like MessagePart/ToolUIPart are imported or
re-exported as needed), keep UI-specific symbols (CollapsedToolGroup,
MessagePartRenderer) in the component, and update any references to the moved
functions; ensure imports/exports are typed and run unit/compile checks after
the refactor.
🤖 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/backend/backend/copilot/sdk/service.py`:
- Around line 1201-1214: The code is scheduling _try_upload_transcript twice
(once during success path and again in the finally), causing duplicate uploads;
fix it by ensuring only one scheduling occurs: either remove the duplicate
create_task call in the finally block or add a guard before scheduling that
checks whether a transcript upload task for this session is already present in
_background_tasks (e.g., track the returned task or set a boolean flag like
transcript_upload_scheduled, or check membership of the created task) and only
call asyncio.create_task(_try_upload_transcript(...)) when not already
scheduled; ensure any task added still uses _background_tasks.add(task) and
task.add_done_callback(_background_tasks.discard) so cleanup remains intact.

In
`@autogpt_platform/frontend/src/app/`(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsx:
- Around line 230-239: splitReasoningAndResponse() and the subsequent
buildRenderSegments() call are slicing message.parts which resets partIndex to 0
and causes MessagePartRenderer to receive incorrect indices; fix by preserving
the original partIndex values from message.parts when creating reasoning and
response arrays (e.g., annotate each part with its original index or map parts
to include an originalIndex before splitting) and ensure buildRenderSegments()
and MessagePartRenderer consume that original index (referencing
splitReasoningAndResponse, buildRenderSegments, MessagePartRenderer, and
message.parts).

In
`@autogpt_platform/frontend/src/app/`(platform)/copilot/components/ChatMessagesContainer/components/CollapsedToolGroup.tsx:
- Around line 93-123: The toggle button in CollapsedToolGroup is missing ARIA
state wiring: add aria-expanded={expanded} to the <button> (the one that calls
setExpanded) and give the panel <div> a stable id (use React's useId or derive
from label, e.g., panelId) then add aria-controls={panelId} on the button and
id={panelId} on the panel <div>; optionally mark the panel with role="region"
and aria-labelledby pointing back to the button to improve screen-reader context
for the parts rendering block.

In
`@autogpt_platform/frontend/src/app/`(platform)/copilot/components/ChatMessagesContainer/components/FeedbackModal.tsx:
- Around line 43-50: The Textarea in FeedbackModal currently relies on a
placeholder and needs an accessible label; update the FeedbackModal component to
give the Textarea an explicit accessible name by either adding a <label> element
associated with the Textarea's id (use htmlFor and set id on the Textarea) or by
passing a clear aria-label prop to the Textarea (e.g., aria-label="Feedback" or
similar descriptive text); ensure the Textarea component (used in FeedbackModal)
receives the id/aria-label so screen readers announce the field purpose.

In
`@autogpt_platform/frontend/src/app/`(platform)/copilot/helpers/convertChatSessionToUiMessages.ts:
- Around line 184-190: The current merge in convertChatSessionToUiMessages
unconditionally combines any consecutive assistant messages (prevUI and msg),
collapsing distinct assistant turns; change the condition so merging only
happens for continuation/tool-continuation responses. Update the if that uses
prevUI, msg.role, and parts to additionally check a clear continuation marker
(e.g., a continuation flag on msg like msg.metadata?.continuation or
msg.isContinuation, or by inspecting parts for a tool/continuation source such
as parts[0].source === 'tool' or parts[0].isContinuation) so that only true
continuations are merged; keep the rest of the logic
(prevUI.parts.push(...parts); return;) unchanged and locate this change inside
convertChatSessionToUiMessages near prevUI, parts, and msg references.

In
`@autogpt_platform/frontend/src/app/`(platform)/copilot/tools/GenericTool/helpers.ts:
- Around line 92-97: The browser_act case currently interpolates inp.target
regardless of its type, which can produce “[object Object]” in status text;
update the case in helpers.ts (the "browser_act" branch handling inp.action and
inp.target) to check that inp.target is a string before using template
interpolation — if typeof inp.target !== "string" then fall back to returning
just inp.action (or null if action isn't a string) so only string targets are
composed into the summary.

---

Nitpick comments:
In
`@autogpt_platform/frontend/src/app/`(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsx:
- Around line 27-152: Move the non-UI logic from the component into a new helper
module: create ChatMessagesContainer/helpers.ts and export isCompletedToolPart,
buildRenderSegments, splitReasoningAndResponse, and renderSegments from it;
update ChatMessagesContainer.tsx to import those functions instead of defining
them inline (ensure renderSegments still returns React.ReactNode[] and that
types like MessagePart/ToolUIPart are imported or re-exported as needed), keep
UI-specific symbols (CollapsedToolGroup, MessagePartRenderer) in the component,
and update any references to the moved functions; ensure imports/exports are
typed and run unit/compile checks after the refactor.

In
`@autogpt_platform/frontend/src/app/`(platform)/copilot/components/ChatMessagesContainer/components/FeedbackModal.tsx:
- Line 40: In FeedbackModal.tsx replace hardcoded slate classes with
design-token color utilities: locate the <p> elements in the FeedbackModal
component that currently use "text-slate-600" and "text-slate-400" (and any
similar slate-* uses) and swap them for the semantic token classes used across
the app (for example "text-muted-foreground" or the appropriate token for
secondary text) by updating their className props; ensure you only change the
color utility while preserving other classes on those elements so theming
remains consistent with the design system.

In
`@autogpt_platform/frontend/src/app/`(platform)/copilot/components/ChatMessagesContainer/useMessageFeedback.ts:
- Around line 22-37: The raw fetch call in useMessageFeedback (sending to
/api/chat/sessions/{sessionID}/feedback with args.sessionID, args.messageID,
args.scoreName, args.scoreValue, args.comment) should be replaced with the
generated API mutation hook from "@/app/api/__generated__/endpoints/" (the hook
following the pattern use{Method}{Version}{OperationName}, e.g., the POST hook
for /chat/sessions/{sessionID}/feedback); import that hook, call it instead of
fetch, and pass the sessionID and payload (message_id, score_name, score_value,
comment) so you get the built-in auth, error handling and typings consistent
with other Copilot API calls.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 21f549e7-2b50-4312-927c-abe105cde7d3

📥 Commits

Reviewing files that changed from the base of the PR and between 0215332 and a1ad8e1.

📒 Files selected for processing (19)
  • autogpt_platform/backend/backend/copilot/sdk/service.py
  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatContainer/ChatContainer.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/components/AssistantMessageActions.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/components/CollapsedToolGroup.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/components/FeedbackModal.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/components/ReasoningCollapse.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/useMessageFeedback.ts
  • autogpt_platform/frontend/src/app/(platform)/copilot/helpers/convertChatSessionToUiMessages.ts
  • autogpt_platform/frontend/src/app/(platform)/copilot/tools/CreateAgent/helpers.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/tools/EditAgent/helpers.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/tools/GenericTool/GenericTool.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/tools/GenericTool/helpers.ts
  • autogpt_platform/frontend/src/app/(platform)/copilot/tools/RunAgent/RunAgent.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/tools/RunAgent/helpers.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/tools/RunBlock/helpers.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/tools/RunMCPTool/helpers.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/useCopilotStream.ts
  • autogpt_platform/frontend/src/components/ai-elements/message.tsx

Comment thread autogpt_platform/backend/backend/copilot/sdk/service.py Outdated
Comment thread autogpt_platform/frontend/src/app/(platform)/copilot/tools/GenericTool/helpers.ts 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.

♻️ Duplicate comments (1)
autogpt_platform/backend/backend/copilot/sdk/service.py (1)

1199-1212: ⚠️ Potential issue | 🟠 Major

Prevent duplicate transcript upload scheduling across success path and finally.

At Line 1203 and again at Line 1303, _try_upload_transcript(...) can be enqueued for the same turn. On successful runs this may create duplicate concurrent uploads.

Suggested fix
@@
     captured_transcript = CapturedTranscript()
     sdk_cwd = ""
+    transcript_upload_scheduled = False
@@
             if raw_transcript:
                 task = asyncio.create_task(
                     _try_upload_transcript(
@@
                 )
                 _background_tasks.add(task)
                 task.add_done_callback(_background_tasks.discard)
+                transcript_upload_scheduled = True
@@
-        if config.claude_agent_use_resume and user_id:
+        if (
+            config.claude_agent_use_resume
+            and user_id
+            and not transcript_upload_scheduled
+        ):
             try:
@@
                 if raw_transcript and session is not None:
                     task = asyncio.create_task(
                         _try_upload_transcript(
@@
                     )
                     _background_tasks.add(task)
                     task.add_done_callback(_background_tasks.discard)
+                    transcript_upload_scheduled = True

Also applies to: 1292-1312

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@autogpt_platform/backend/backend/copilot/sdk/service.py` around lines 1199 -
1212, The code schedules _try_upload_transcript(...) twice (once on the success
path and again in the finally block), which can create duplicate concurrent
uploads; fix by making upload scheduling idempotent: introduce a single upload
task variable/flag (e.g., upload_task or upload_scheduled) in the scope of the
generator/turn and set it when you call
asyncio.create_task(_try_upload_transcript(...)); in the finally block only
create/schedule the upload if that variable/flag is not already set. Update uses
of _background_tasks and task.add_done_callback to use the single created task
and avoid creating a second one.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@autogpt_platform/backend/backend/copilot/sdk/service.py`:
- Around line 1199-1212: The code schedules _try_upload_transcript(...) twice
(once on the success path and again in the finally block), which can create
duplicate concurrent uploads; fix by making upload scheduling idempotent:
introduce a single upload task variable/flag (e.g., upload_task or
upload_scheduled) in the scope of the generator/turn and set it when you call
asyncio.create_task(_try_upload_transcript(...)); in the finally block only
create/schedule the upload if that variable/flag is not already set. Update uses
of _background_tasks and task.add_done_callback to use the single created task
and avoid creating a second one.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: e45eef83-1158-4a4d-8a20-7f7b449de0f9

📥 Commits

Reviewing files that changed from the base of the PR and between a1ad8e1 and 299fd9e.

📒 Files selected for processing (1)
  • autogpt_platform/backend/backend/copilot/sdk/service.py
📜 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 (4)
autogpt_platform/backend/**/*.py

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

autogpt_platform/backend/**/*.py: Use Python 3.11 (required; managed by Poetry via pyproject.toml) for backend development
Always run 'poetry run format' (Black + isort) before linting in backend development
Always run 'poetry run lint' (ruff) after formatting in backend development

Files:

  • autogpt_platform/backend/backend/copilot/sdk/service.py
autogpt_platform/backend/**/*.{py,txt}

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

Use poetry run prefix for all Python commands, including testing, linting, formatting, and migrations

Files:

  • autogpt_platform/backend/backend/copilot/sdk/service.py
autogpt_platform/backend/backend/**/*.py

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

Use Prisma ORM for database operations in PostgreSQL with pgvector for embeddings

Files:

  • autogpt_platform/backend/backend/copilot/sdk/service.py
autogpt_platform/**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

Format Python code with poetry run format

Files:

  • autogpt_platform/backend/backend/copilot/sdk/service.py
🧠 Learnings (2)
📚 Learning: 2026-02-26T17:02:22.448Z
Learnt from: Pwuts
Repo: Significant-Gravitas/AutoGPT PR: 12211
File: .pre-commit-config.yaml:160-179
Timestamp: 2026-02-26T17:02:22.448Z
Learning: Keep the pre-commit hook pattern broad for autogpt_platform/backend to ensure OpenAPI schema changes are captured. Do not narrow to backend/api/ alone, since the generated schema depends on Pydantic models across multiple directories (backend/data/, backend/blocks/, backend/copilot/, backend/integrations/, backend/util/). Narrowing could miss schema changes and cause frontend type desynchronization.

Applied to files:

  • autogpt_platform/backend/backend/copilot/sdk/service.py
📚 Learning: 2026-03-04T08:04:35.881Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12273
File: autogpt_platform/backend/backend/copilot/tools/workspace_files.py:216-220
Timestamp: 2026-03-04T08:04:35.881Z
Learning: In the AutoGPT Copilot backend, ensure that SVG images are not treated as vision image types by excluding 'image/svg+xml' from INLINEABLE_MIME_TYPES and MULTIMODAL_TYPES in tool_adapter.py; the Claude API supports PNG, JPEG, GIF, and WebP for vision. SVGs (XML text) should be handled via the text path instead, not the vision path.

Applied to files:

  • autogpt_platform/backend/backend/copilot/sdk/service.py

@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 (2)
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/components/CollapsedToolGroup.tsx (1)

33-80: Avoid duplicating tool-category icon mapping.

EntryIcon mirrors ToolIcon logic in autogpt_platform/frontend/src/app/(platform)/copilot/tools/GenericTool/GenericTool.tsx. This will drift as categories evolve. Consider sharing a single icon-mapping helper/component between both call sites.

🤖 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/components/CollapsedToolGroup.tsx
around lines 33 - 80, The EntryIcon implementation duplicates the
icon-to-category mapping used by ToolIcon (in GenericTool.tsx); extract the
mapping into a single shared helper or component (e.g., getToolIcon or
SharedToolIcon) and have both EntryIcon and ToolIcon call that shared
function/component. Update EntryIcon (the function in CollapsedToolGroup.tsx) to
import and delegate to the shared helper instead of re-implementing the switch,
and remove the duplicated switch logic from both locations so future category
changes are made in one place.
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsx (1)

42-58: Keep CUSTOM_TOOL_TYPES in a shared single source of truth.

This list must stay aligned with the custom-tool cases in MessagePartRenderer. If one side changes and this set doesn’t, tools can be collapsed incorrectly. Consider extracting this list to a shared constant consumed by both files.

🤖 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 42 - 58, CUSTOM_TOOL_TYPES in ChatMessagesContainer.tsx is
duplicated and can drift out of sync with the custom-tool cases in
MessagePartRenderer; extract the set into a shared constant module (e.g., export
const CUSTOM_TOOL_TYPES) and import it from both ChatMessagesContainer (where
the set is currently declared) and MessagePartRenderer so both files reference
the same source of truth, update imports/usages to use the shared symbol
CUSTOM_TOOL_TYPES, and remove the local declaration to prevent divergence.
🤖 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/tools/GenericTool/helpers.ts:
- Around line 124-132: In the "TodoWrite" switch branch, guard each todo before
accessing properties: when computing todos and using todos.find(...) (the
variable todos and the resulting active), ensure the finder callback verifies
the item is a non-null object (e.g., t !== null && typeof t === "object") before
reading t.status; likewise check active exists and its activeForm/content are
strings before returning them (references: the "TodoWrite" case, todos, active,
activeForm, content).

---

Nitpick comments:
In
`@autogpt_platform/frontend/src/app/`(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsx:
- Around line 42-58: CUSTOM_TOOL_TYPES in ChatMessagesContainer.tsx is
duplicated and can drift out of sync with the custom-tool cases in
MessagePartRenderer; extract the set into a shared constant module (e.g., export
const CUSTOM_TOOL_TYPES) and import it from both ChatMessagesContainer (where
the set is currently declared) and MessagePartRenderer so both files reference
the same source of truth, update imports/usages to use the shared symbol
CUSTOM_TOOL_TYPES, and remove the local declaration to prevent divergence.

In
`@autogpt_platform/frontend/src/app/`(platform)/copilot/components/ChatMessagesContainer/components/CollapsedToolGroup.tsx:
- Around line 33-80: The EntryIcon implementation duplicates the
icon-to-category mapping used by ToolIcon (in GenericTool.tsx); extract the
mapping into a single shared helper or component (e.g., getToolIcon or
SharedToolIcon) and have both EntryIcon and ToolIcon call that shared
function/component. Update EntryIcon (the function in CollapsedToolGroup.tsx) to
import and delegate to the shared helper instead of re-implementing the switch,
and remove the duplicated switch logic from both locations so future category
changes are made in one place.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: a5325ccb-20b0-4435-8777-d185f433a704

📥 Commits

Reviewing files that changed from the base of the PR and between 224663b and d3f9507.

📒 Files selected for processing (6)
  • autogpt_platform/backend/backend/copilot/sdk/service.py
  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/components/CollapsedToolGroup.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/components/FeedbackModal.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/tools/GenericTool/GenericTool.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/tools/GenericTool/helpers.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/components/FeedbackModal.tsx
  • autogpt_platform/backend/backend/copilot/sdk/service.py
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: Seer Code Review
  • GitHub Check: Check PR Status
  • GitHub Check: test (3.11)
  • GitHub Check: test (3.13)
  • GitHub Check: test (3.12)
  • GitHub Check: end-to-end tests
🧰 Additional context used
📓 Path-based instructions (13)
autogpt_platform/frontend/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

autogpt_platform/frontend/**/*.{ts,tsx,js,jsx}: Use Node.js 21+ with pnpm package manager for frontend development
Always run 'pnpm format' for formatting and linting code in frontend development

autogpt_platform/frontend/**/*.{ts,tsx,js,jsx}: Run pnpm format to auto-fix formatting issues before completing work
Run pnpm lint to check for lint errors and fix any that appear before completing work

Files:

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

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

autogpt_platform/frontend/**/*.{tsx,ts}: Use function declarations for components and handlers (not arrow functions) in React components
Only use arrow functions for small inline lambdas (map, filter, etc.) in React components
Use PascalCase for component names and camelCase with 'use' prefix for hook names in React
Use Tailwind CSS utilities only for styling in frontend components
Use design system components from 'src/components/' (atoms, molecules, organisms) in frontend development
Never use 'src/components/legacy/' in frontend code
Only use Phosphor Icons (@phosphor-icons/react) for icons in frontend components
Use generated API hooks from '@/app/api/generated/endpoints/' instead of deprecated 'BackendAPI' or 'src/lib/autogpt-server-api/
'
Use React Query for server state (via generated hooks) in frontend development
Default to client components ('use client') in Next.js; only use server components for SEO or extreme TTFB needs
Use '' component for rendering errors in frontend UI; use toast notifications for mutation errors; use 'Sentry.captureException()' for manual exceptions
Separate render logic from data/behavior in React components; keep comments minimal (code should be self-documenting)

Files:

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

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

autogpt_platform/frontend/**/*.{ts,tsx}: No barrel files or 'index.ts' re-exports in frontend code
Regenerate API hooks with 'pnpm generate:api' after backend OpenAPI spec changes in frontend development

Run pnpm types to check for type errors and fix any that appear before completing work

Files:

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

📄 CodeRabbit inference engine (AGENTS.md)

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

autogpt_platform/frontend/src/**/*.{ts,tsx}: Use function declarations (not arrow functions) for components and handlers
Use type-safe generated API hooks via Orval + React Query for data fetching
Use React Query for server state management and co-locate UI state in components/hooks
Separate render logic (.tsx) from business logic (use*.ts hooks)
Use only shadcn/ui (Radix UI primitives) with Tailwind CSS for UI components
Use Phosphor Icons only for all icon implementations
Use ErrorCard component for render errors, toast for mutations, and Sentry for exceptions
Use design system components 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 specific function
Never type with any unless a variable/attribute can actually be of any type

Files:

  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/components/CollapsedToolGroup.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/tools/GenericTool/GenericTool.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/tools/GenericTool/helpers.ts
autogpt_platform/frontend/**/*.{js,jsx,ts,tsx,css}

📄 CodeRabbit inference engine (AGENTS.md)

Use Tailwind CSS only for styling, use design tokens, and use Phosphor Icons only

Files:

  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/components/CollapsedToolGroup.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/tools/GenericTool/GenericTool.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/tools/GenericTool/helpers.ts
autogpt_platform/frontend/src/**/*.tsx

📄 CodeRabbit inference engine (AGENTS.md)

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

Use type Props = { ... } (not exported) for component props unless used outside the component

Files:

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

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

Fully capitalize acronyms in symbols, e.g. graphID, useBackendAPI

Files:

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

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

Put sub-components in a local components/ folder within the feature directory

Files:

  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/components/CollapsedToolGroup.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsx
autogpt_platform/frontend/src/**/[A-Z]*/**/*.{ts,tsx}

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

Structure components as ComponentName/ComponentName.tsx + useComponentName.ts + helpers.ts

Files:

  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/components/CollapsedToolGroup.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/tools/GenericTool/GenericTool.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/tools/GenericTool/helpers.ts
autogpt_platform/frontend/src/**/*.ts

📄 CodeRabbit inference engine (AGENTS.md)

Do not type hook returns, let Typescript infer as much as possible

Files:

  • autogpt_platform/frontend/src/app/(platform)/copilot/tools/GenericTool/helpers.ts
🧠 Learnings (18)
📓 Common learnings
Learnt from: Pwuts
Repo: Significant-Gravitas/AutoGPT PR: 12284
File: autogpt_platform/frontend/src/app/api/openapi.json:11897-11900
Timestamp: 2026-03-04T23:58:09.319Z
Learning: Repo: Significant-Gravitas/AutoGPT — PR `#12284`
Backend/frontend OpenAPI codegen convention: In backend/api/features/store/model.py, the StoreSubmission and StoreSubmissionAdminView models define submitted_at: datetime | None, changes_summary: str | None, and instructions: str | None with no default. This is intentional to produce “required but nullable” fields in OpenAPI (properties appear in required[] and use anyOf [type, null]). This matches Prisma’s submittedAt DateTime? and changesSummary String?. Do not flag this as a required/nullable mismatch.
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:55.700Z
Learning: As of PR `#12213`, MCP tool response types (MCPToolsDiscoveredResponse, MCPToolOutputResponse) are defined in openapi.json and frontend code in autogpt_platform/frontend/src/app/(platform)/copilot/tools/RunMCPTool/helpers.tsx uses the generated types from `@/app/api/__generated__/`. Other tools like RunBlock still use inline TypeScript interfaces (e.g., BlockDetailsResponse) for SSE stream payloads that are not included in openapi.json schemas. The pattern is tool-specific: use generated types when available in openapi.json, use inline types only when the payload schema is truly SSE-stream-only and not exposed via OpenAPI.
📚 Learning: 2026-02-04T16:50:51.495Z
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-02-04T16:50:51.495Z
Learning: Applies to autogpt_platform/frontend/src/**/*.{ts,tsx} : Colocate state when possible, avoid creating large components, use sub-components in local `/components` folder

Applied to files:

  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/components/CollapsedToolGroup.tsx
📚 Learning: 2026-02-04T16:50:51.495Z
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-02-04T16:50:51.495Z
Learning: Applies to 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)

Applied to files:

  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/components/CollapsedToolGroup.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/tools/GenericTool/GenericTool.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/tools/GenericTool/helpers.ts
📚 Learning: 2026-02-04T16:49:42.490Z
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2026-02-04T16:49:42.490Z
Learning: Applies to autogpt_platform/frontend/src/components/**/*.{tsx,ts} : Structure React components as: ComponentName/ComponentName.tsx + useComponentName.ts + helpers.ts (exception: small 3-4 line components can be inline; render-only components can be direct files)

Applied to files:

  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/components/CollapsedToolGroup.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/tools/GenericTool/GenericTool.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/tools/GenericTool/helpers.ts
📚 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/components/CollapsedToolGroup.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/tools/GenericTool/GenericTool.tsx
📚 Learning: 2026-02-26T21:29:44.105Z
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: autogpt_platform/frontend/CLAUDE.md:0-0
Timestamp: 2026-02-26T21:29:44.105Z
Learning: Applies to autogpt_platform/frontend/src/**/[A-Z]*/**/*.{ts,tsx} : Structure components as ComponentName/ComponentName.tsx + useComponentName.ts + helpers.ts

Applied to files:

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

Applied to files:

  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/components/CollapsedToolGroup.tsx
📚 Learning: 2026-02-26T10:12:58.845Z
Learnt from: 0ubbe
Repo: Significant-Gravitas/AutoGPT PR: 12207
File: autogpt_platform/frontend/src/components/ai-elements/conversation.tsx:0-0
Timestamp: 2026-02-26T10:12:58.845Z
Learning: Guideline: Do not apply dark mode CSS classes (e.g., dark:text-*) to copilot UI components until dark mode support is implemented. Applies to all copilot-related components (paths containing /copilot/). When reviewing, search for dark:* class names within copilot components and refactor to use conditional class sets or feature-flag gates, ensuring no dark-mode styles are present in the code paths that render copilot UI unless dark mode support is officially enabled.

Applied to files:

  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/components/CollapsedToolGroup.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/tools/GenericTool/GenericTool.tsx
📚 Learning: 2026-02-04T16:50:51.495Z
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-02-04T16:50:51.495Z
Learning: Applies to autogpt_platform/frontend/src/**/*.{ts,tsx} : Separate render logic from business logic with component.tsx + useComponent.ts + helpers.ts structure

Applied to files:

  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/tools/GenericTool/GenericTool.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/tools/GenericTool/helpers.ts
📚 Learning: 2026-02-26T21:29:44.105Z
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: autogpt_platform/frontend/CLAUDE.md:0-0
Timestamp: 2026-02-26T21:29:44.105Z
Learning: Applies to autogpt_platform/frontend/src/**/*.{ts,tsx} : Separate render logic (`.tsx`) from business logic (`use*.ts` hooks)

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} : 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:51.495Z
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-02-04T16:50:51.495Z
Learning: Applies to autogpt_platform/frontend/src/**/*.{ts,tsx} : Avoid large hooks, abstract logic into `helpers.ts` files when sensible

Applied to files:

  • autogpt_platform/frontend/src/app/(platform)/copilot/tools/GenericTool/GenericTool.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/tools/GenericTool/helpers.ts
📚 Learning: 2026-02-26T21:29:44.105Z
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: autogpt_platform/frontend/CLAUDE.md:0-0
Timestamp: 2026-02-26T21:29:44.105Z
Learning: Applies to autogpt_platform/frontend/**/*.{ts,tsx} : Run `pnpm types` to check for type errors and fix any that appear before completing work

Applied to files:

  • autogpt_platform/frontend/src/app/(platform)/copilot/tools/GenericTool/GenericTool.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/tools/GenericTool/helpers.ts
📚 Learning: 2026-02-26T21:29:44.105Z
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: autogpt_platform/frontend/CLAUDE.md:0-0
Timestamp: 2026-02-26T21:29:44.105Z
Learning: Applies to autogpt_platform/frontend/src/**/*.{ts,tsx,js,jsx} : Fully capitalize acronyms in symbols, e.g. `graphID`, `useBackendAPI`

Applied to files:

  • autogpt_platform/frontend/src/app/(platform)/copilot/tools/GenericTool/GenericTool.tsx
📚 Learning: 2026-02-26T21:29:44.105Z
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: autogpt_platform/frontend/CLAUDE.md:0-0
Timestamp: 2026-02-26T21:29:44.105Z
Learning: Applies to autogpt_platform/frontend/**/*.{ts,tsx,js,jsx} : Run `pnpm format` to auto-fix formatting issues before completing work

Applied to files:

  • autogpt_platform/frontend/src/app/(platform)/copilot/tools/GenericTool/GenericTool.tsx
  • autogpt_platform/frontend/src/app/(platform)/copilot/tools/GenericTool/helpers.ts
📚 Learning: 2026-02-04T16:50:51.495Z
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-02-04T16:50:51.495Z
Learning: Applies to autogpt_platform/frontend/**/*.{js,jsx,ts,tsx,css} : Use Tailwind CSS only for styling, use design tokens, and use Phosphor Icons only

Applied to files:

  • autogpt_platform/frontend/src/app/(platform)/copilot/tools/GenericTool/GenericTool.tsx
📚 Learning: 2026-02-27T10:45:55.700Z
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:55.700Z
Learning: As of PR `#12213`, MCP tool response types (MCPToolsDiscoveredResponse, MCPToolOutputResponse) are defined in openapi.json and frontend code in autogpt_platform/frontend/src/app/(platform)/copilot/tools/RunMCPTool/helpers.tsx uses the generated types from `@/app/api/__generated__/`. Other tools like RunBlock still use inline TypeScript interfaces (e.g., BlockDetailsResponse) for SSE stream payloads that are not included in openapi.json schemas. The pattern is tool-specific: use generated types when available in openapi.json, use inline types only when the payload schema is truly SSE-stream-only and not exposed via OpenAPI.

Applied to files:

  • autogpt_platform/frontend/src/app/(platform)/copilot/tools/GenericTool/helpers.ts
📚 Learning: 2026-02-26T21:29:44.105Z
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: autogpt_platform/frontend/CLAUDE.md:0-0
Timestamp: 2026-02-26T21:29:44.105Z
Learning: Applies to autogpt_platform/frontend/src/**/use*.ts : Extract component logic into custom hooks grouped by concern, with each hook in its own `.ts` file

Applied to files:

  • autogpt_platform/frontend/src/app/(platform)/copilot/tools/GenericTool/helpers.ts
🔇 Additional comments (4)
autogpt_platform/frontend/src/app/(platform)/copilot/tools/GenericTool/helpers.ts (1)

7-72: Nice centralization of tool-name/category logic.

This extraction makes downstream UI rendering paths more consistent and easier to maintain.

autogpt_platform/frontend/src/app/(platform)/copilot/tools/GenericTool/GenericTool.tsx (1)

34-40: Good move extracting helper logic into helpers.ts.

This keeps GenericTool focused on rendering concerns.

As per coding guidelines: "Separate render logic from business logic with component.tsx + useComponent.ts + helpers.ts structure".

autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/components/CollapsedToolGroup.tsx (1)

94-99: ARIA state wiring looks correct now.

aria-expanded + aria-controls on the trigger and a matching panel id are correctly connected.

Also applies to: 125-127

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

65-103: Good fix for preserving original partIndex values.

Using baseIndex plus responseStartIndex keeps MessagePartRenderer indices stable after reasoning/response splitting.

Also applies to: 268-275

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

This comment was marked as outdated.

0ubbe and others added 2 commits March 6, 2026 18:45
…s in FeedbackModal

Revert fire-and-forget transcript upload back to blocking asyncio.shield
per reviewer feedback to avoid concurrency issues. Replace hardcoded
slate color classes with text-muted-foreground design tokens.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@github-actions github-actions Bot removed the platform/backend AutoGPT Platform - Back end label Mar 6, 2026
majdyz
majdyz previously approved these changes Mar 6, 2026
@github-project-automation github-project-automation Bot moved this from 🆕 Needs initial review to 👍🏼 Mergeable in AutoGPT development kanban Mar 6, 2026
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@0ubbe
0ubbe merged commit 7507240 into dev Mar 6, 2026
21 checks passed
@0ubbe
0ubbe deleted the lluisagusti/secrt-2024-collapse-repeated-block-executions-into-grouped-summary-rows branch March 6, 2026 13:22
@github-project-automation github-project-automation Bot moved this from 👍🏼 Mergeable to ✅ Done in AutoGPT development kanban Mar 6, 2026
@github-project-automation github-project-automation Bot moved this to Done in Frontend Mar 6, 2026
majdyz pushed a commit that referenced this pull request Mar 6, 2026
…ompletion (#12282)

## Summary
- **Frontend:** Group consecutive completed generic tool parts into
collapsible summary rows with a "Reasoning" collapse for finalized
messages. Merge consecutive assistant messages on hydration to avoid
split bubbles. Extract GenericTool helpers. Add `reconnectExhausted`
state and a brief delay before refetching session to reduce stale
`active_stream` reconnect cycles.
- **Backend:** Make transcript upload fire-and-forget instead of
blocking the generator exit. The 30s upload timeout in
`_try_upload_transcript` was delaying `mark_session_completed()`,
keeping the SSE stream alive with only heartbeats after the LLM had
finished — causing the UI to stay stuck in "streaming" state.

## Test plan
- [ ] Send a message in Copilot that triggers multiple tool calls —
verify they collapse into a grouped summary row once completed
- [ ] Verify the final text response appears below the collapsed
reasoning section
- [ ] Confirm the stream properly closes after the agent finishes (no
stuck "Stop" button)
- [ ] Refresh mid-stream and verify reconnection works correctly
- [ ] Click Stop during streaming — verify the UI becomes responsive
immediately

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
majdyz pushed a commit that referenced this pull request Mar 8, 2026
…ompletion (#12282)

## Summary
- **Frontend:** Group consecutive completed generic tool parts into
collapsible summary rows with a "Reasoning" collapse for finalized
messages. Merge consecutive assistant messages on hydration to avoid
split bubbles. Extract GenericTool helpers. Add `reconnectExhausted`
state and a brief delay before refetching session to reduce stale
`active_stream` reconnect cycles.
- **Backend:** Make transcript upload fire-and-forget instead of
blocking the generator exit. The 30s upload timeout in
`_try_upload_transcript` was delaying `mark_session_completed()`,
keeping the SSE stream alive with only heartbeats after the LLM had
finished — causing the UI to stay stuck in "streaming" state.

## Test plan
- [ ] Send a message in Copilot that triggers multiple tool calls —
verify they collapse into a grouped summary row once completed
- [ ] Verify the final text response appears below the collapsed
reasoning section
- [ ] Confirm the stream properly closes after the agent finishes (no
stuck "Stop" button)
- [ ] Refresh mid-stream and verify reconnection works correctly
- [ ] Click Stop during streaming — verify the UI becomes responsive
immediately

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
itsababseh added a commit that referenced this pull request Mar 13, 2026
…abricated items, add missing links

Changes:
- Notifications: #12258#12364 (correct PR for autopilot notification system)
- Reasoning: #12346#12282 (collapse repeated tool calls, more accurate)
- Improvements: fix pinned tool cards description, add ↗ links to all items
- Fixes: replace 6 fabricated/vague items with 6 real PRs from v0.6.51
- Under the hood: fix Mistral model names, add ↗ links to all items
okxint pushed a commit to okxint/AutoGPT that referenced this pull request Mar 24, 2026
…ompletion (Significant-Gravitas#12282)

## Summary
- **Frontend:** Group consecutive completed generic tool parts into
collapsible summary rows with a "Reasoning" collapse for finalized
messages. Merge consecutive assistant messages on hydration to avoid
split bubbles. Extract GenericTool helpers. Add `reconnectExhausted`
state and a brief delay before refetching session to reduce stale
`active_stream` reconnect cycles.
- **Backend:** Make transcript upload fire-and-forget instead of
blocking the generator exit. The 30s upload timeout in
`_try_upload_transcript` was delaying `mark_session_completed()`,
keeping the SSE stream alive with only heartbeats after the LLM had
finished — causing the UI to stay stuck in "streaming" state.

## Test plan
- [ ] Send a message in Copilot that triggers multiple tool calls —
verify they collapse into a grouped summary row once completed
- [ ] Verify the final text response appears below the collapsed
reasoning section
- [ ] Confirm the stream properly closes after the agent finishes (no
stuck "Stop" button)
- [ ] Refresh mid-stream and verify reconnection works correctly
- [ ] Click Stop during streaming — verify the UI becomes responsive
immediately

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------
okxint pushed a commit to okxint/AutoGPT that referenced this pull request Mar 24, 2026
…ompletion (Significant-Gravitas#12282)

## Summary
- **Frontend:** Group consecutive completed generic tool parts into
collapsible summary rows with a "Reasoning" collapse for finalized
messages. Merge consecutive assistant messages on hydration to avoid
split bubbles. Extract GenericTool helpers. Add `reconnectExhausted`
state and a brief delay before refetching session to reduce stale
`active_stream` reconnect cycles.
- **Backend:** Make transcript upload fire-and-forget instead of
blocking the generator exit. The 30s upload timeout in
`_try_upload_transcript` was delaying `mark_session_completed()`,
keeping the SSE stream alive with only heartbeats after the LLM had
finished — causing the UI to stay stuck in "streaming" state.

## Test plan
- [ ] Send a message in Copilot that triggers multiple tool calls —
verify they collapse into a grouped summary row once completed
- [ ] Verify the final text response appears below the collapsed
reasoning section
- [ ] Confirm the stream properly closes after the agent finishes (no
stuck "Stop" button)
- [ ] Refresh mid-stream and verify reconnection works correctly
- [ ] Click Stop during streaming — verify the UI becomes responsive
immediately

🤖 Generated with [Claude Code](https://claude.com/claude-code)

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

Labels

platform/frontend AutoGPT Platform - Front end size/xl

Projects

Status: ✅ Done
Status: Done

Development

Successfully merging this pull request may close these issues.

3 participants