Skip to content

refactor(frontend): ONE agent overview — body, actions menu and rail, on both surfaces - #5884

Draft
ardaerzin wants to merge 12 commits into
pkg/agent-overview-layoutfrom
pkg/agent-overview-body
Draft

refactor(frontend): ONE agent overview — body, actions menu and rail, on both surfaces#5884
ardaerzin wants to merge 12 commits into
pkg/agent-overview-layoutfrom
pkg/agent-overview-body

Conversation

@ardaerzin

Copy link
Copy Markdown
Contributor

The lane below shared the agent-overview frame. This one shares the body: the composition
itself, the actions menu (antd-free, both surfaces), the composer, the rail's usage card, and the
rail's collapse toggle and version label.

Eight commits, mostly /m catching up to the shared components and then fixing what that exposed
— column heights, page margins, the kebab sitting beside the title instead of at the far edge, and
the version label rendering on the vertical rail too.
Not run in a browser — static gates only (pnpm lint-fix 24/24, tsc --noEmit clean
for @agenta/shared, ui, entities, entity-ui, settings-ui, oss, ee, mobile).

Stacked on pkg/agent-overview-layout; review only this lane's diff.

@ardaerzin

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@vercel

vercel Bot commented Aug 10, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
agenta-documentation Error Error Aug 11, 2026 5:11am

Request Review

@coderabbitai

coderabbitai Bot commented Aug 10, 2026

Copy link
Copy Markdown
⚠️ Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai

coderabbitai Bot commented Aug 10, 2026

Copy link
Copy Markdown

Review Change Stack

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: 29a09c13-3075-492f-8d43-0bc3bb23718e

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Summary by CodeRabbit

  • New Features
    • Added shared agent overview layouts with session lists, usage details, files, triggers, and configuration content.
    • Added agent action menus for renaming, deleting, configuring, and copying agent details.
    • Added agent-specific task composition with fixed agent selection and session routing.
    • Added collapsible mobile navigation controls.
    • Added version information to the Help & Docs navigation item when available.
  • Improvements
    • Standardized session cards and agent overview experiences across desktop and mobile.
    • Added configurable task composer placeholders and improved empty/loading states.

Walkthrough

The PR consolidates agent overview layouts into shared UI components, adds reusable agent and session actions, introduces mobile agent composition, and centralizes sidebar navigation controls and version display.

Changes

Agent overview consolidation

Layer / File(s) Summary
Shared overview and session components
web/packages/agenta-entity-ui/..., web/packages/agenta-sessions-ui/..., web/packages/agenta-entity-ui/package.json
Adds shared agent overview, session list, agent file, and package export components.
Reusable agent actions
web/packages/agenta-entity-ui/src/agent/AgentActionsMenu.tsx, web/packages/agenta-entity-ui/src/agent/useAgentActions.tsx, web/oss/src/pages/.../overview/index.tsx
Adds shared copy, rename, configure, and delete actions and integrates the action menu into the agent overview.
Desktop overview integration
web/oss/src/components/pages/overview/agent/AgentOverview.tsx, web/oss/src/components/pages/sessions/components/*
Replaces custom desktop overview and session-list logic with shared components and session-card verbs.
Mobile agent overview and composer
web/mobile/src/features/agents/*, web/packages/agenta-home-ui/src/HomeTaskComposer.tsx
Adds fixed-agent task composition and updates the mobile overview to use shared overview, usage, session, and action components.
Shared navigation controls and version label
web/packages/agenta-navigation-ui/src/*, web/mobile/src/features/nav/*, web/oss/src/components/Sidebar/components/SidebarToggleButton.tsx
Adds a shared sidebar toggle, displays navigation suffixes, and loads the package version for the Help & Docs item.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant AgentOverview
  participant AgentOverviewBody
  participant SessionListCard
  participant useSessionCardVerbs
  AgentOverview->>AgentOverviewBody: render overview props
  AgentOverviewBody->>SessionListCard: render scoped session cards
  SessionListCard->>useSessionCardVerbs: use row and menu callbacks
  useSessionCardVerbs->>AgentOverview: open selected agent session
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description check ✅ Passed The description clearly explains the shared agent overview refactor, affected surfaces, layout fixes, validation, and review scope.
Title check ✅ Passed The title clearly identifies the agent overview refactor and its shared body, actions menu, and rail across both surfaces.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch pkg/agent-overview-body

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.

@ardaerzin

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 10, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🧹 Nitpick comments (3)
web/packages/agenta-entity-ui/src/agent/AgentActionsMenu.tsx (1)

13-29: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Reduce the new implementation comments.

These comments exceed the repository limit. Keep only short comments that describe non-obvious constraints.

  • web/packages/agenta-entity-ui/src/agent/AgentActionsMenu.tsx#L13-L29: Remove or reduce the prop and component comments to one short line each.
  • web/packages/agenta-entity-ui/src/agent/useAgentActions.tsx#L16-L22: Remove or reduce the hook comment to one short line.
  • web/oss/src/pages/w/[workspace_id]/p/[project_id]/apps/[app_id]/overview/index.tsx#L63-L64: Remove or reduce the host-flow comment to one short line.

As per coding guidelines, keep in-code comments to at most one short line.

Source: Coding guidelines

web/packages/agenta-home-ui/src/HomeTaskComposer.tsx (1)

69-96: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Run the formatter on this block.

The <span> wrapper was added around the existing Select, but the Select subtree keeps its previous indentation, so lines 74-93 are misaligned inside the new element. This indicates the formatter did not run on this change.

As per coding guidelines: "Before committing frontend changes, run pnpm lint-fix from the web directory."

Source: Coding guidelines

web/packages/agenta-entity-ui/src/agent/AgentFilesCard.tsx (1)

124-133: 🚀 Performance & Scalability | 🔵 Trivial | 💤 Low value

Hoist TooltipProvider out of rows.map.

A shared provider preserves Radix skip-delay behavior across file triggers and avoids one provider context per row. The local provider does not render a DOM wrapper.


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: daa09821-d4fd-4182-b0ac-3bb90533ffc5

📥 Commits

Reviewing files that changed from the base of the PR and between 001fad6 and 4218be4.

⛔ Files ignored due to path filters (1)
  • web/pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (23)
  • web/mobile/src/features/agents/AgentComposer.tsx
  • web/mobile/src/features/agents/AgentOverviewScreen.tsx
  • web/mobile/src/features/agents/AgentOverviewSection.tsx
  • web/mobile/src/features/nav/mobileNavScope.tsx
  • web/mobile/src/features/nav/useMobileNavItems.tsx
  • web/oss/src/components/Sidebar/components/SidebarToggleButton.tsx
  • web/oss/src/components/pages/overview/agent/AgentConfigurationCard.tsx
  • web/oss/src/components/pages/overview/agent/AgentOverview.tsx
  • web/oss/src/components/pages/sessions/components/SessionListCard.tsx
  • web/oss/src/components/pages/sessions/components/useSessionCardVerbs.ts
  • web/oss/src/pages/w/[workspace_id]/p/[project_id]/apps/[app_id]/overview/index.tsx
  • web/packages/agenta-entity-ui/package.json
  • web/packages/agenta-entity-ui/src/agent/AgentActionsMenu.tsx
  • web/packages/agenta-entity-ui/src/agent/AgentFilesCard.tsx
  • web/packages/agenta-entity-ui/src/agent/AgentOverviewBody.tsx
  • web/packages/agenta-entity-ui/src/agent/index.ts
  • web/packages/agenta-entity-ui/src/agent/useAgentActions.tsx
  • web/packages/agenta-home-ui/src/HomeTaskComposer.tsx
  • web/packages/agenta-navigation-ui/src/NavMenu.tsx
  • web/packages/agenta-navigation-ui/src/SidebarToggleButton.tsx
  • web/packages/agenta-navigation-ui/src/index.ts
  • web/packages/agenta-sessions-ui/src/SessionListCard.tsx
  • web/packages/agenta-sessions-ui/src/index.ts
💤 Files with no reviewable changes (2)
  • web/mobile/src/features/agents/AgentOverviewSection.tsx
  • web/oss/src/components/pages/overview/agent/AgentConfigurationCard.tsx

Comment on lines +31 to +37
const start = async ({text}: {agentId: string; text: string}) => {
const staged = attachments.files
const parts = staged.length > 0 ? stagedFilesToParts(staged, sessionId) : undefined
stash({sessionId, task: {agentId, text, parts}})
attachments.clearAttachments(staged.map((file) => file.uid))
await router.push(`${base}/sessions/${sessionId}?agent=${agentId}`)
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Handle a failed router.push in start.

start clears the staged attachments and stashes the pending task before it navigates. If router.push rejects, the task stays in pendingTasksAtom under a session that the user never opens, the attachments are already cleared, and the rejection propagates out of the composer's submit handler as an unhandled rejection. The desktop equivalent guards this: useOpenAgentSession in web/oss/src/components/AgentChatSlice/hooks/useOpenAgentSession.ts clears the pending target when the push fails.

🛡️ Proposed fix
     const start = async ({text}: {agentId: string; text: string}) => {
         const staged = attachments.files
         const parts = staged.length > 0 ? stagedFilesToParts(staged, sessionId) : undefined
         stash({sessionId, task: {agentId, text, parts}})
         attachments.clearAttachments(staged.map((file) => file.uid))
-        await router.push(`${base}/sessions/${sessionId}?agent=${agentId}`)
+        // Drop the stashed task on a failed navigation, or it is adopted by the next session view.
+        await router.push(`${base}/sessions/${sessionId}?agent=${agentId}`).catch(() => {
+            clearPendingTask(sessionId)
+        })
     }

web/mobile/src/features/home/pendingTask.ts currently exposes only stashPendingTaskAtom; add a matching clear writer there.

{/* The same verbs the desktop header offers; rename and delete
fall through to the shared implementations here, since /m has
no app-management modals of its own. */}
<AgentActionsMenu agent={{id: agentId, name, slug: agent?.slug}} />

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Render AgentActionsMenu only after the agent record resolves.

While agentsQuery is pending, agent is undefined and name falls back to "Agent" (line 40). The menu is interactive at that point, so a rename started early is seeded with the placeholder name, and the destructive verbs act on an agent whose real name and slug are unknown.

🐛 Proposed fix
-                                <AgentActionsMenu agent={{id: agentId, name, slug: agent?.slug}} />
+                                {agent ? (
+                                    <AgentActionsMenu
+                                        agent={{id: agentId, name, slug: agent.slug}}
+                                    />
+                                ) : null}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<AgentActionsMenu agent={{id: agentId, name, slug: agent?.slug}} />
{agent ? (
<AgentActionsMenu
agent={{id: agentId, name, slug: agent.slug}}
/>
) : null}

Comment on lines +75 to +81
<AgentOverviewBody
agentId={appId}
sessionsHref={sessionsHref ?? ""}
onEditConfig={openConfig}
usage={<UsageSummary variant="strip" />}
{...verbs}
composer={

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Avoid passing an empty sessionsHref.

Line 57 leaves sessionsHref undefined until appURL resolves. Line 77 then passes "". Both list cards render their "View all" link and the waiting badge with href="", which resolves to the current route, so the click applies the session scope but does not navigate. Prefer a project-level fallback, or render the cards only after appURL resolves.

🐛 Proposed fix using the project sessions route as fallback
-    const {appURL} = useURL()
-    const sessionsHref = appURL ? `${appURL}/sessions` : undefined
+    const {appURL, projectURL} = useURL()
+    const sessionsHref = `${appURL || projectURL}/sessions`
-            sessionsHref={sessionsHref ?? ""}
+            sessionsHref={sessionsHref}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<AgentOverviewBody
agentId={appId}
sessionsHref={sessionsHref ?? ""}
onEditConfig={openConfig}
usage={<UsageSummary variant="strip" />}
{...verbs}
composer={
const {appURL, projectURL} = useURL()
const sessionsHref = `${appURL || projectURL}/sessions`
<AgentOverviewBody
agentId={appId}
sessionsHref={sessionsHref}
onEditConfig={openConfig}
usage={<UsageSummary variant="strip" />}
{...verbs}
composer={

Comment on lines +58 to +65
// Every link out of this card lands on the set the card was showing, not on a default list.
const linkScope = useMemo(() => ({agentId: null, origin}), [origin])
const handleViewAll = useCallback(() => {
applyScope(linkScope)
}, [applyScope, linkScope])
const handleWaitingClick = useCallback(() => {
applyScope({...linkScope, status: "waiting"})
}, [applyScope, linkScope])

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Inspect the scope contract and how hosts re-apply agent scope on the sessions route.
rg -n 'applySessionScopeAtom' -C 15 web/packages/agenta-sessions/src | head -80
rg -n 'agentId' -C 3 web/packages/agenta-sessions/src/state/scope*.ts 2>/dev/null | head -60

Repository: Agenta-AI/agenta

Length of output: 4119


🏁 Script executed:

#!/bin/bash
set -e
printf '%s\n' '--- SessionListCard.tsx ---'
cat -n web/packages/agenta-sessions-ui/src/SessionListCard.tsx | sed -n '1,180p'

printf '%s\n' '--- session scope state ---'
cat -n web/packages/agenta-sessions/src/state/filters.ts | sed -n '1,130p'

printf '%s\n' '--- SessionListCard usages and host props ---'
rg -n -C 12 'SessionListCard|viewAllHref|base}/sessions|base.*sessions' web --glob '*.{ts,tsx}' | head -300

Repository: Agenta-AI/agenta

Length of output: 38110


🏁 Script executed:

#!/bin/bash
set -e
printf '%s\n' '--- SessionListPanel scope implementation ---'
cat -n web/packages/agenta-sessions-ui/src/SessionListPanel.tsx | sed -n '35,115p'

printf '%s\n' '--- Agent overview host ---'
cat -n web/packages/agenta-entity-ui/src/agent/AgentOverviewBody.tsx | sed -n '1,180p'

printf '%s\n' '--- sessionsHref definitions and route consumers ---'
rg -n -C 8 'sessionsHref' web/packages --glob '*.{ts,tsx}' | head -240

printf '%s\n' '--- sessions page filter initialization and navigation ---'
rg -n -C 10 'sessionAgentFilterAtom|sessionShowTriggeredAtom|applySessionScopeAtom|usePathname|sessions' web/packages/agenta-sessions-ui web/packages/agenta-sessions --glob '*.{ts,tsx}' | head -320

Repository: Agenta-AI/agenta

Length of output: 50372


🏁 Script executed:

#!/bin/bash
set -e
printf '%s\n' '--- AgentOverviewBody callers ---'
rg -l 'AgentOverviewBody' web --glob '*.{ts,tsx}' | sort

printf '%s\n' '--- sessionsHref assignments and literal sessions routes ---'
rg -n 'sessionsHref\s*=|sessionsHref:|base}/sessions|/sessions' web --glob '*.{ts,tsx}' | grep -E 'sessionsHref|base.*/sessions|href|sessions' | head -220

printf '%s\n' '--- route filter atom consumers ---'
rg -n -C 6 'sessionAgentFilterAtom|sessionShowTriggeredAtom|sessionStatusFilterAtom' web/packages/agenta-sessions web/packages/agenta-sessions-ui --glob '*.{ts,tsx}' | head -220

Repository: Agenta-AI/agenta

Length of output: 41407


Preserve agentId in linkScope. The desktop route re-applies the agent scope, but mobile navigates to project-wide ${base}/sessions. applySessionScopeAtom then resets the agent filter, so both “View all” and “waiting” can show sessions from other agents. Use {agentId: agentId ?? null, origin} and include agentId in the memo dependencies.

…st the frame

The components on this page were already shared; the ARRANGEMENT was not, so /m
assembled its own sections in its own order and was missing Files and Usage
entirely. AgentOverviewBody is the whole body — composer slot, both list cards,
and the rail in one order (what the agent IS, CARRIES, WILL DO, COST) — rendered
by the desktop page and the mobile screen alike.

SessionListCard moves to @agenta/sessions-ui with the three app verbs as props
(mobile's useSessionRowMenu already returns exactly those), replacing mobile's
own AgentOverviewSection. AgentFilesCard moves to @agenta/entity-ui/agent,
de-antd'd so mobile can render it. The OSS wrappers those two replaced are gone.
/m already had a start-session composer on Home; the agent page had none. Rather
than a second composer, HomeTaskComposer gains fixedAgentId — with it the picker
drops, because an agent's own page already answers which agent and a picker there
would let you send from it to a different one. AgentComposer is the mobile
binding, on HomeComposer's mint-stash-route flow so attachments staged before the
session exists keep their scope.
…s its margins

ContentRail renders a plain div, so the body's `flex-1`/`h-full` columns had no
definite height to resolve against and the left one scrolled inside a stunted
box. Making the wrapper a flex column restores the chain. Padding scales with the
viewport — tight on a phone, desktop-like margins from lg.
…sktop margins

UsageCard already serves /m's home and takes an appId, so the agent rail scopes it
to this agent — the same figures the desktop strip shows. Margins go from 24px to
64px at lg, measured against the desktop page rather than guessed.
The kebab lived in the OSS page: an antd Dropdown wired to app-management modals,
with /m offering nothing. AgentActionsMenu is the shared verb set — rename, copy
id, copy slug, delete — on Radix, and useAgentActions is its default
implementation (updateWorkflow / archiveWorkflow, both already in entities), built
the way useSessionActions already does shared verbs.

Rename and delete take host overrides so the desktop keeps its app-management
modals, which validate and refresh the apps cache; /m has none and falls through
to the shared ones. Copying is shared outright. The swap left the OSS header's
antd Dropdown, Button, MoreOutlined and copyToClipboard imports dead; they're gone.
The title carried flex-1, so it absorbed the row and pushed the menu to the
opposite end. Sizing it to its text puts the two together as on the desktop;
min-w-0 keeps a long name truncating.
… shared ones

Both were desktop-only. SidebarToggleButton moves to @agenta/navigation-ui — it
needed nothing OSS-specific once sidebarCollapsedAtom was in @agenta/navigation
and EnhancedButton was antd-free — and takes collapsedAtom as a prop so it does
not quietly bypass SidebarShell's own contract. The OSS path stays a re-export
because settingsScope imports it too. The version rides buildHelpDocsNavItem's
suffix, lazy-loaded from mobile's own package.json.
Help & Docs is a group inside a `vertical` bottom section, so NavMenu draws it
through the flyout trigger, not RowLabel — where the suffix had been ported. The
label was therefore missing on BOTH the desktop rail and /m. Drawn on both paths
now; the collapsed icon rail still omits it, as 111 intended.
… antd items

useSessionCardVerbs handed actions.menuItems() straight to SessionListCard's
menuFor, which is typed (vm) => SessionMenuEntry[]. antd's MenuProps["items"]
admits null entries, groups and submenus, so the shapes do not line up.
toSessionMenuEntries is the existing converter the sessions page already used.
…inks to

The extraction into `@agenta/sessions-ui` hardcoded `linkScope.agentId` to null, so
"View all" and the waiting badge cleared the agent filter on the way out. On /m,
whose sessions route is project-wide and narrows by that filter alone, both landed
the user on every agent's sessions.

The original conditional keyed on whether the host passed a `viewAllHref` at all,
which no longer discriminates: both hosts pass one, and what differs is where it
points. The desktop's is the agent's OWN sessions route, which re-applies the scope
from the route — setting the filter there is invisible (the page hides the chip) but
survives to the next project-wide list. So the distinction becomes an explicit
`viewAllScopesAgent`, threaded through `AgentOverviewBody`: set on the desktop,
absent on /m, and by default the agent travels with the link.

While the app id is still resolving, the desktop now falls back to the project
sessions route (correct, because the flag then carries the agent as a filter) rather
than passing `""` — a link back to the current route, i.e. a click that visibly does
nothing. `viewAllHref` is optional for the window where even the project is unknown:
"View all" is then not offered and the waiting badge renders as plain text, instead
of holding the whole page or offering a dead link.
…gent is known

The actions menu was interactive while the agents query was still pending, when
`name` is the "Agent" placeholder and the slug is unknown. A rename opened seeded
with the placeholder, and archive and delete acted on a record the screen could not
yet describe. The menu now waits for the record, which is how the rest of the screen
already treats an unresolved agent — no skeleton, since the kebab is last in the
header row and nothing shifts when it arrives.
…the attachments

`AgentComposer` stashed the pending task and dropped the staged attachments before
navigating, then awaited the push without handling it. A push that rejects left the
task under a session id the user was never taken to — where it would fire at whoever
opened that id later — took the attachments with it, and let the rejection escape the
composer's submit handler.

The push is now resolved both ways the Pages Router can fail it (`false` on a
cancelled route change, a rejection on a real one), and neither leaves residue: the
stash comes back out through `dropPendingTaskAtom`, and the attachments go back in
the tray. They still have to be cleared BEFORE the navigation — the chat screen's
composer restores this session's staged rows from the per-session store, so rows left
behind would return as a second copy of what the first turn already carries — which
is why `useComposerAttachments` grows the `restoreAttachments` counterpart to
`clearAttachments`. It re-stages the entries settled rather than through `addFiles`,
which would upload them a second time.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant