Skip to content

feat(widget): conversation thread list — list, new, switch, auto-title - #59

Open
AmitAvital1 wants to merge 1 commit into
feat/widget-context-usagefrom
feat/widget-thread-list
Open

feat(widget): conversation thread list — list, new, switch, auto-title#59
AmitAvital1 wants to merge 1 commit into
feat/widget-context-usagefrom
feat/widget-thread-list

Conversation

@AmitAvital1

Copy link
Copy Markdown
Collaborator

Stack 3/4 · base: feat/widget-context-usage (#58)

Adds a conversation thread drawer to the widget: list past chats, start a new one, and switch between them. Thread identity is anonymous per-browser now (crypto.randomUUID() in localStorage) with an <agent-chat user="..."> seam for future host-app identity. Titles are auto-generated on the backend from the first user message (thread_title), keeping the FE a pure pipe.

Backend adds list_sessions / rename_session to the repository port (memory + SQL adapters) and GET /conversations?user_id.

Verified: make check + widget typecheck/e2e green.

🤖 Generated with Claude Code

Let a user see their past conversations, start a new one, and switch
between them, backed by the agent manager as the source of truth.

Backend:
- Repository.list_sessions(user_id) + rename_session (port, memory, sql)
- GET /conversations?user_id=... returns id, title, last_message_at
  (most-recently-active first); ConversationService.list_conversations
- thread_title() derives a title from the first user message; the service
  sets it on the first turn of a conversation

Widget (stateless; BE owns the list and titles):
- anonymous per-browser user id in localStorage, sent on create/list; an
  optional <agent-chat user="..."> attribute overrides it, leaving the
  seam for real host identity later
- AgentChatClient.listConversations + useConversation listThreads/
  switchTo/startNew
- header history + new-chat buttons and a slide-over thread drawer;
  switching loads that thread's messages and usage; drawer is inert when
  closed. Degrades to empty list against a backend without the endpoint

Tests: listing scoped by user, auto-title, and a widget e2e for the
drawer (list, switch, new chat).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@Asaf-prog

Copy link
Copy Markdown
Collaborator

PR #59

The thread-list feature looks good, but I see a few identity and conversation-ownership issues that should be addressed before merging.

First, the active conversation ID is stored using only the endpoint. It should also be scoped by userId; otherwise, when a different user signs in on the same browser, the widget may reuse the previous user’s conversation.

Second, user_id is sent when the conversation is created, but it is not sent or derived during send and stream. As a result, the agent execution can run with RunContext.user_id = None.

The backend should load the conversation session, validate that it belongs to the authenticated user, and derive the user identity from the session rather than trusting a user_id supplied by the browser.

The new conversation-list endpoint also accepts user_id directly from the query string. This is fine as a temporary anonymous-browser identifier, but it should not be treated as an authorization boundary.

I would request changes here before merging, especially because user identity can affect tool access and authorization.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ui enhancement User-facing UI improvement

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants