Skip to content

Fix/settings edit hook issues#2860

Merged
dokterbob merged 2 commits intoChainlit:mainfrom
Allaoua9:fix/settings-edit-hook-issues
Apr 1, 2026
Merged

Fix/settings edit hook issues#2860
dokterbob merged 2 commits intoChainlit:mainfrom
Allaoua9:fix/settings-edit-hook-issues

Conversation

@Allaoua9
Copy link
Copy Markdown
Contributor

@Allaoua9 Allaoua9 commented Mar 26, 2026

This PR was implemented in collaboration with @tonca, many thanks to him !

Summary

Improves chat settings behavior around live edits (on_settings_edit), session vs UI state, and Reset / Cancel after dynamic schema updates from the server.

Problems

  1. ChatSettings.send() and committed session
    send() always called set_chat_settings, so using it from @cl.on_settings_edit to refresh widgets also overwrote session.chat_settings. Committed settings should only change on submit (chat_settings_change / on_settings_update), not on every in-form edit.

  2. Spurious chat_settings_edit events
    The modal used watch() + useEffect to emit edits. Any form update—including reset() after a server chat_settings push—could emit again, so the backend could see duplicate or misleading edit events.

  3. Reset / Cancel vs “when I opened”
    Reset used chat_settingsDefaultValue (current schema initials), not the state when the panel opened. After a server-driven refresh, Reset and Cancel could leave the new widget list while trying to revert values.

What we changed

Backend

  • ChatSettings.refresh() — Pushes the same chat_settings payload as send(), but does not call set_chat_settings, so session chat_settings stays unchanged until the user confirms.
  • send() — Unchanged behavior: still updates session and emits; shared _inputs_as_dicts() keeps payload building in one place.
  • Teststest_chat_settings_refresh asserts set_chat_settings is not called and chat_settings is emitted.

Frontend

  • User-driven edit events only — Removed watch + useEffect for edits. setFieldValue now calls setValue then editChatSettings(getValues()), so reset() / Recoil sync do not emit edits. Applied in modal and sidebar.
  • Snapshot at openuseChatSettingsSnapshotAtOpen captures chatSettingsValue and chatSettingsInputs when the panel opens (not on every prop change while open).
  • Restore on Reset / CancelrestoreSnapshot() writes cloneDeep snapshots back into chatSettingsInputsState and chatSettingsValueState, so schema and values both match pre-open state; existing useEffectreset(chatSettingsValue) keeps react-hook-form aligned.

Result

  • Apps can use await cl.ChatSettings([...]).refresh() inside on_settings_edit to refresh the form without mutating committed session settings.
  • chat_settings_edit is tied to real control changes, not programmatic resets.
  • Reset and close without confirm restore both the input schema and values from when the user opened the panel.

Follow-ups (optional)

  • Debounce editChatSettings for sliders if event volume is an issue.
  • Docs / examples — Point dynamic-widget examples at refresh() instead of send() where session should not be updated on edit.

Summary by cubic

Fixes chat settings live edits so the UI can refresh without overwriting session settings, prevents spurious edit events, and makes Reset/Cancel restore the state from when the panel opened.

  • New Features

    • Added ChatSettings.refresh() to emit chat_settings UI updates without updating session settings. Use it in on_settings_edit (e.g., await cl.ChatSettings([...]).refresh()).
    • Added useChatSettingsSnapshotAtOpen to snapshot inputs and values at open; used in modal and sidebar.
  • Bug Fixes

    • Edits no longer mutate session.chat_settings; settings are committed only on Confirm/Submit.
    • chat_settings_edit now fires only on user changes; programmatic reset() or server-driven updates no longer emit.
    • Reset and Cancel restore both the input schema and values to the pre-open snapshot, even after dynamic schema updates.

Written for commit 325cd1c. Summary will update on new commits.

Allaoua Benchikh added 2 commits March 26, 2026 17:25
@dosubot dosubot bot added size:XL This PR changes 500-999 lines, ignoring generated files. backend Pertains to the Python backend. frontend Pertains to the frontend. labels Mar 26, 2026
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

No issues found across 5 files

Copy link
Copy Markdown
Contributor

@hayescode hayescode left a comment

Choose a reason for hiding this comment

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

Reviewed via Codex

LGTM.

@dokterbob dokterbob added this pull request to the merge queue Apr 1, 2026
Merged via the queue into Chainlit:main with commit fe1b384 Apr 1, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backend Pertains to the Python backend. frontend Pertains to the frontend. size:XL This PR changes 500-999 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants