Skip to content

improvement(chat): defer resource-menu list queries until the menu opens - #5973

Merged
waleedlatif1 merged 3 commits into
stagingfrom
fix/large-chat-loading
Jul 27, 2026
Merged

improvement(chat): defer resource-menu list queries until the menu opens#5973
waleedlatif1 merged 3 commits into
stagingfrom
fix/large-chat-loading

Conversation

@waleedlatif1

@waleedlatif1 waleedlatif1 commented Jul 27, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • The + resource menu and the @-mention menu both hydrate from useAvailableResources, which fired nine workspace-wide list queries and rebuilt ten item groups on mount — from two always-mounted call sites, for menus that were closed. Now gated on each menu's own state.
  • Added options.enabled to the six query hooks that lacked it, matching the convention already used by useWorkspaceFiles / useKnowledgeBasesQuery / useLogsList.
  • The tab-name lookup no longer fires its five list queries when there are no tabs to label.
  • Dropped the = [] destructuring defaults in the aggregator — a literal default allocates a fresh array every render while data is undefined, which busted the group memo in exactly the disabled state. Disabled now returns a module-scope constant, so the four downstream memos stay stable too.
  • Moved the hook call into PlusMenuDropdown (the component that owns the open state), removing the availableResources pass-through from usePromptEditorPromptEditor. This also restores the React.memo boundary on PlusMenuDropdown, which the array prop was defeating on every keystroke.
  • Deleted the existingKeys/isOpen plumbing threaded through AvailableItem, both tree-node unions and both onSelect signatures — PlusMenuDropdown never read it. Resolved at the single call site instead.

Not losing mentions while the lists load

Deferring the lists introduced a window where the mention candidates were empty. That mattered more than it first looked: selectActive() returning falsy makes the keydown handler fall through and submit the message, with the mention left as raw text. Closed in two steps:

  • Warm on focusPlusMenuDropdown gates on open || warm, and PromptEditor latches warm on the textarea's first focus. Focus is the earliest reliable signal a mention may be coming, so the lists are in flight well before anyone can type @, while still staying off the page-load path.
  • Make readiness explicit — warming shrinks the race but doesn't guarantee readiness, so useAvailableResources now reports isHydrating and PlusMenuHandle.selectActive returns selected | empty | hydrating. Tab/Enter are swallowed while hydrating and only fall through once the lists have settled, where an empty result is a genuine no-match. isHydrating keys off isPending rather than data === undefined, so a failed list settles instead of blocking the key forever.

Found while investigating a customer report of slow chat loading. Worth being clear about scope: this is a real reduction in work per chat load, but it is not the fix for that report. The dominant costs there are the embedded workflow editor mounting inside the chat, the block/tool registry in the route's initial bundle, and a ~294 KB transcript — all separate follow-ups.

Type of Change

  • Improvement

Testing

Tested manually. Typecheck clean, bun run lint:check 19/19, 249 home tests pass, check:react-query / check:api-validation / check:client-boundary all pass.

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

@vercel

vercel Bot commented Jul 27, 2026

Copy link
Copy Markdown

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

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Skipped Skipped Jul 27, 2026 7:17pm

Request Review

@cursor

cursor Bot commented Jul 27, 2026

Copy link
Copy Markdown

PR Summary

Medium Risk
Touches chat input key handling and lazy query gating across multiple menus; wrong hydration or enabled logic could block mentions or leave stale empty menus, but changes are localized to UI/query options with no auth or data-model changes.

Overview
Defers nine workspace-wide list queries that powered the + and @ resource menus so they no longer run on every chat mount. useAvailableResources now takes { enabled, excludeTypes }, returns { groups, isHydrating }, and only runs its queries when a menu is open or warmed (textarea first focus). The add-tab dropdown gates on open; PlusMenuDropdown owns the hook and receives workspaceId + warm instead of a pre-built array from usePromptEditor.

Mention safety while lists load: PlusMenuHandle.selectActive returns selected | empty | hydrating, and Tab/Enter are swallowed while isHydrating so an empty candidate list does not submit the message with raw @ text. Tab name lookup skips its five queries when there are no open resource tabs.

Cleanup: Removed isOpen / existingKeys threading through menu items; switching to an already-open tab uses existingKeys at selection time. Added enabled to several React Query hooks (useWorkflows, useTablesList, useFolders, etc.). Stable empty memo constants avoid busting downstream memos when queries are disabled.

Reviewed by Cursor Bugbot for commit 6a44068. Configure here.

@greptile-apps

greptile-apps Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

Defers workspace resource-list queries until relevant menus are opened or warmed.

  • Adds enabled support to resource query hooks and stable disabled-state results.
  • Warms mention resources on editor focus and distinguishes selected, empty, and hydrating confirmation states.
  • Moves resource hydration into the menu owner and avoids tab-name queries when no resource tabs exist.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains in the current follow-up scope.

Important Files Changed

Filename Overview
apps/sim/app/workspace/[workspaceId]/home/components/mothership-view/components/add-resource-dropdown/add-resource-dropdown.tsx Centralizes deferred resource hydration, stable empty groups, and aggregate pending state without an eligible follow-up defect.
apps/sim/app/workspace/[workspaceId]/home/components/user-input/components/plus-menu-dropdown/plus-menu-dropdown.tsx Moves queries behind menu readiness and safely distinguishes hydration from a settled empty candidate list.
apps/sim/app/workspace/[workspaceId]/home/components/user-input/components/prompt-editor/prompt-editor.tsx Latches query warming on first editable-textarea focus.
apps/sim/app/workspace/[workspaceId]/home/components/user-input/components/prompt-editor/use-prompt-editor.ts Prevents Enter and Tab from falling through while mention candidates are hydrating.
apps/sim/app/workspace/[workspaceId]/home/components/mothership-view/components/resource-tabs/resource-tabs.tsx Disables tab-name list queries when there are no resource tabs and stabilizes the empty lookup.
apps/sim/hooks/queries/workflows.ts Adds optional query enablement while preserving default behavior.
apps/sim/hooks/queries/tables.ts Adds optional query enablement while preserving existing polling configuration.
apps/sim/hooks/queries/folders.ts Adds optional query enablement alongside the existing workspace guard.
apps/sim/hooks/queries/mothership-chats.ts Adds optional query enablement while retaining skip-token handling.
apps/sim/hooks/queries/schedules.ts Adds optional query enablement alongside the existing workspace guard.
apps/sim/hooks/queries/workspace-file-folders.ts Adds optional query enablement without changing the default fetch behavior.

Reviews (4): Last reviewed commit: "fix(chat): never submit a mention while ..." | Re-trigger Greptile

The `+` resource menu and the `@`-mention menu both hydrate from
`useAvailableResources`, which fired nine workspace-wide list queries and
rebuilt ten item groups on mount — from two always-mounted call sites, for
menus that were closed. Gate it on each menu's own open state.

- add an `enabled` option to `useAvailableResources`; pass `open` from
  `AddResourceDropdown` and `PlusMenuDropdown`
- add `options.enabled` to the six query hooks that lacked it, matching the
  convention already used by `useWorkspaceFiles` / `useKnowledgeBasesQuery` /
  `useLogsList`
- skip the tab-name lookup's five list queries when there are no tabs to label
- drop the `= []` destructuring defaults: a literal default allocates a fresh
  array every render while `data` is undefined, busting the group memo in
  exactly the disabled state
- move the hook call into `PlusMenuDropdown`, which owns the open state,
  removing the `availableResources` pass-through from `usePromptEditor`
- delete the `existingKeys`/`isOpen` plumbing — one consumer never read it;
  resolve it at the single call site instead
Deferring the lists to menu-open left a window where `selectActive()` saw an
empty candidate list, and its `false` return falls through to submitting the
message with the mention unresolved. Start hydrating on first focus — the
earliest reliable signal a mention may be coming — which closes the window
while keeping the lists off the page-load path.
@waleedlatif1
waleedlatif1 force-pushed the fix/large-chat-loading branch from 6e7177e to 8f224ce Compare July 27, 2026 19:09
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cursor review

Warming on focus shrank the race but gave no readiness guarantee: an empty
candidate list still meant "no match" to the keydown handler, which falls
through and submits the message with the mention as raw text.

Make the distinction explicit. `useAvailableResources` now reports
`isHydrating`, and `PlusMenuHandle.selectActive` returns
`selected | empty | hydrating` instead of a boolean. The editor swallows
Tab/Enter while hydrating and only lets them through once the lists have
settled, where an empty result is a genuine no-match.

`isHydrating` keys off `isPending`, not `data === undefined`, so a failed
list settles instead of blocking the key forever.
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cursor review

@cursor cursor 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.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 6a44068. Configure here.

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1
waleedlatif1 merged commit 54c3e1c into staging Jul 27, 2026
21 checks passed
@waleedlatif1
waleedlatif1 deleted the fix/large-chat-loading branch July 27, 2026 20:21
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