Conversation
- Replace useMessageAggregationContext with prop drilling for assistantGroupId, fixing crash when ApprovalActions renders outside MessageAggregationContext - Filter out tmp_ message IDs from pending interventions to prevent disabled buttons during message creation - Portal ApprovalActions outside scroll container in InterventionBar so buttons are always accessible for long content - Clear stale displayMessages synchronously on topic change to prevent old interventions from persisting during transitions
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
@arvinxx - This is a tool calling intervention fix (InterventionBar context errors, rendering, and topic transition). Please take a look. |
Codecov Reportβ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## canary #13420 +/- ##
===========================================
- Coverage 86.92% 66.56% -20.37%
===========================================
Files 598 1944 +1346
Lines 45649 158244 +112595
Branches 7775 15160 +7385
===========================================
+ Hits 39682 105328 +65646
- Misses 5847 52796 +46949
Partials 120 120
Flags with carried forward coverage won't be shown. Click here to find out more.
π New features to boost your workflow:
|
Replace render-phase side effect with useLayoutEffect to properly clear displayMessages before browser paint when context changes, preventing old topic interventions from flashing during transitions.
There was a problem hiding this comment.
π‘ Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 52591ac8cd
βΉοΈ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with π.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
β¦ata flash Use React's "setState during render" pattern instead of useLayoutEffect. When contextKey changes, React bails out and re-renders StoreUpdater before rendering sibling components (ChatList/ChatInput), ensuring they read fresh store state with no visible flash of old topic data.
Add key={contextKey} to zustand Provider so the store is recreated on
topic switch. Seed the new store with initialMessages in createStore to
render correct data on first mount β no intermediate skeleton or stale
flash. Remove render-phase reset hack from StoreUpdater as it's no
longer needed.
β¦reset
Provider key={contextKey} caused ChatHydration to remount and reset
activeTopicId from URL query, preventing topic switches entirely.
Reverted to stable Provider. Instead, use useLayoutEffect in StoreUpdater
to atomically reset displayMessages + messagesInit when contextKey changes.
This fires after commit but before paint, and React processes store updates
from layout effects synchronously, ensuring subscribers re-render with
correct state before the browser paints.
|
@codex review |
There was a problem hiding this comment.
π‘ Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 43adf1a8f9
βΉοΈ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with π.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if (messages) { | ||
| storeApi.getState().replaceMessages(messages); | ||
| storeApi.setState({ messagesInit: true }); |
There was a problem hiding this comment.
Update context before replacing messages on context switch
Calling replaceMessages(messages) inside this useLayoutEffect runs before useStoreUpdater('context', context) applies the new context (that updater uses useEffect), so replaceMessages still reads the previous get().context when invoking onMessagesChange. On topic/thread switches where messages is already populated (e.g., cached target conversation), this can write the new conversation's messages back into the previous conversation key in ChatStore, corrupting cached data until a refetch fixes it.
Useful? React with πΒ / π.
|
β€οΈ Great PR @Innei β€οΈ The growth of project is inseparable from user feedback and contribution, thanks for your contribution! If you are interesting with the lobehub developer community, please join our discord and then dm @arvinxx or @canisminor1990. They will invite you to our private developer channel. We are talking about the lobe-chat development or sharing ai newsletter around the world. |
β¦g, and topic transition issues (lobehub#13420) * π fix: resolve InterventionBar context errors and rendering issues - Replace useMessageAggregationContext with prop drilling for assistantGroupId, fixing crash when ApprovalActions renders outside MessageAggregationContext - Filter out tmp_ message IDs from pending interventions to prevent disabled buttons during message creation - Portal ApprovalActions outside scroll container in InterventionBar so buttons are always accessible for long content - Clear stale displayMessages synchronously on topic change to prevent old interventions from persisting during transitions * π fix: use useLayoutEffect to clear stale interventions on topic switch Replace render-phase side effect with useLayoutEffect to properly clear displayMessages before browser paint when context changes, preventing old topic interventions from flashing during transitions. * π fix: synchronously reset store on context change to prevent stale data flash Use React's "setState during render" pattern instead of useLayoutEffect. When contextKey changes, React bails out and re-renders StoreUpdater before rendering sibling components (ChatList/ChatInput), ensuring they read fresh store state with no visible flash of old topic data. * π fix: remount store on context change to eliminate stale data flash Add key={contextKey} to zustand Provider so the store is recreated on topic switch. Seed the new store with initialMessages in createStore to render correct data on first mount β no intermediate skeleton or stale flash. Remove render-phase reset hack from StoreUpdater as it's no longer needed. * π fix: revert Provider key approach, use useLayoutEffect for context reset Provider key={contextKey} caused ChatHydration to remount and reset activeTopicId from URL query, preventing topic switches entirely. Reverted to stable Provider. Instead, use useLayoutEffect in StoreUpdater to atomically reset displayMessages + messagesInit when contextKey changes. This fires after commit but before paint, and React processes store updates from layout effects synchronously, ensuring subscribers re-render with correct state before the browser paints.
# π release: 20260407 This release includes **148 commits**. Key updates are below. - **Response API tool execution is more capable and reliable** β Added hosted builtin tools + client-side function tools and improved tool-call streaming/completion behavior. [#13406](#13406) [#13414](#13414) [#13506](#13506) [#13555](#13555) - **Input and composition UX upgraded** β Added AI input auto-completion and multiple chat-input stability fixes. [#13458](#13458) [#13551](#13551) [#13481](#13481) - **Model/provider compatibility improved** β Better Gemini/Google tool schema handling and additional model updates. [#13429](#13429) [#13465](#13465) [#13613](#13613) - **Desktop and CLI reliability improved** β Gateway WebSocket support and desktop runtime upgrades. [#13608](#13608) [#13550](#13550) [#13557](#13557) - **Security hardening continued** β Fixed auth and sanitization risks and upgraded vulnerable dependencies. [#13535](#13535) [#13529](#13529) [#13479](#13479) ### Models & Providers - Added/updated support for `glm-5v-turbo`, GLM-5.1 updates, and qwen3.5-omni series. [#13487](#13487) [#13405](#13405) [#13422](#13422) - Added additional ImageGen providers/models (Wanxiang 2.7 and Keling from Qwen). [#13478](#13478) - Improved Gemini/Google tool schema and compatibility handling across runtime paths. [#13429](#13429) [#13465](#13465) [#13613](#13613) ### Response API & Runtime - Added hosted builtin tools in Response API and client-side function tool execution support. [#13406](#13406) [#13414](#13414) - Improved stream tool-call argument handling and `response.completed` output correctness. [#13506](#13506) [#13555](#13555) - Improved runtime error/context handling for intervention and provider edge cases. [#13420](#13420) [#13607](#13607) ### Desktop App - Bumped desktop dependencies and runtime integrations (`agent-browser`, `electron`). [#13550](#13550) [#13557](#13557) - Simplified desktop release channel setup by removing nightly release flow. [#13480](#13480) ### CLI - Added OpenClaw migration command. [#13566](#13566) - Added local device binding support for `lh agent run`. [#13277](#13277) - Added WebSocket gateway support and reconnect reliability improvements. [#13608](#13608) [#13418](#13418) ### Security - Removed risky `apiKey` fallback behavior in webapi auth path to prevent bypass risk. [#13535](#13535) - Sanitized HTML artifact rendering and iframe sandboxing to reduce XSS-to-RCE risk. [#13529](#13529) - Upgraded nodemailer to v8 to address SMTP command injection advisory. [#13479](#13479) ### Bug Fixes - Fixed image generation model default switch issues. [#13587](#13587) - Fixed subtopic re-fork message scope behavior and agent panel reset edge cases. [#13606](#13606) [#13556](#13556) - Fixed chat-input freeze on paste and mention plugin behavior. [#13551](#13551) [#13415](#13415) - Fixed auth/social sign-in and settings UX edge cases. [#13368](#13368) [#13392](#13392) [#13338](#13338) ### Credits Huge thanks to these contributors: @chriszf @hardy-one @Innei @lijian @neko @OctopusNote @rdmclin2 @rivertwilight @RylanCai @suyua9 @sxjeru @Tsuki @wangyk @WindSpiritSR @yizhuo @YuTengjing @hezhijie0327 @arvinxx
π» Change Type
π Related Issue
N/A
π Description of Change
Fixes multiple issues with the InterventionBar component after it was moved to render inside ChatInput:
Context crash:
ApprovalActionsuseduseMessageAggregationContext()which throws when rendered outsideMessageAggregationContext(i.e. in ChatInput). Replaced with prop drilling ofassistantGroupIdthroughPendingInterventionβInterventionContentβInterventionβApprovalActions/Fallback.Disabled buttons on tmp_ IDs: Pending interventions were collected before their tool messages were persisted (still had
tmp_prefix IDs), causing approval buttons to be permanently disabled. Now filters outtmp_IDs fromgetPendingInterventions.Actions hidden in scroll: For long intervention content, Reject/Approve buttons were inside the scroll container and unreachable. Used
createPortalto render actions into a fixed container outside the scroll area.Stale interventions on topic switch: Old topic's pending interventions persisted briefly during topic transitions because
displayMessageswasn't cleared synchronously. Added synchronous reset inStoreUpdaterwhencontextKeychanges.π§ͺ How to Test
π Additional Information
The
actionsPortalTargetprop is optional β when not provided (message list context), actions render inline as before. OnlyInterventionBarpasses the portal target.