Is your feature request related to a problem? Please describe.
Chainlit has no user-facing way to mark a thread as "save this one" or to surface specific threads above the time-based sidebar groups (Today / Yesterday / Previous 7 days / Previous 30 days). This matters in two cases:
(1) deployments with retention policies that auto-delete threads after N days need a way for users to flag threads that should be exempt, and;
(2) users who want to keep important chats (decisions, reference conversations, notes) visible without relying on recency-based ordering have no affordance to do so.
Describe the solution you'd like
Native thread pinning with:
- A "Pin" / "Unpin" item in the existing per-thread ... dropdown (alongside Rename / Share / Delete).
- A "Pinned" section at the top of the sidebar showing pinned threads above the time groups. Pinned threads should also still appear in their natural time bucket so recency-based navigation is unaffected.
- Pinned state stored on ThreadDict.metadata.pinned (boolean), giving data layers a stable, queryable place to persist and filter on it, including for retention jobs.
- A DataLayer.update_pinned_state(thread_id, pinned) method and matching REST endpoints (e.g. POST
/project/thread/pin, DELETE /project/thread/pin).
- No pin limit and no time-based restrictions (any thread can be pinned).
Describe alternatives you've considered
- Client-side DOM injection via custom_js: I built a working prototype that registers custom FastAPI endpoints on Chainlit's app, uses a MutationObserver to inject a menu item into the Radix dropdown, and prepends a Pinned" section to #thread-history. It works but depends on private DOM selectors (id="thread-options", id="rename-thread", [data-radix-menu-content]) and on the aria-labelledby / data-state="open" relationships between Radix trigger and menu, none of which are stable across versions.
- Slash command (e.g. /pin): simple to build, but has poor discoverability and doesn't address the sidebar-ordering requirement.
- Separate "saved chats" view: higher friction than a pin toggle and pulls users out of their current flow.
- Generic per-thread tags: more flexible, but there's no user-facing UX for tags today and retention filtering
benefits from a dedicated flag rather than a free-form field.
Additional context
- The cascade order for any retention cleanup script: stage files → ELEMENTS → FEEDBACK → STEPS → THREADS, is non-obvious. A helper such as DataLayer.delete_thread_cascade(thread_id) would pair well with this feature.
Is your feature request related to a problem? Please describe.
Chainlit has no user-facing way to mark a thread as "save this one" or to surface specific threads above the time-based sidebar groups (Today / Yesterday / Previous 7 days / Previous 30 days). This matters in two cases:
(1) deployments with retention policies that auto-delete threads after N days need a way for users to flag threads that should be exempt, and;
(2) users who want to keep important chats (decisions, reference conversations, notes) visible without relying on recency-based ordering have no affordance to do so.
Describe the solution you'd like
Native thread pinning with:
/project/thread/pin, DELETE /project/thread/pin).
Describe alternatives you've considered
benefits from a dedicated flag rather than a free-form field.
Additional context