diff --git a/backend/alembic/versions/26b931506ecb_default_chosen_assistants_to_none.py b/backend/alembic/versions/26b931506ecb_default_chosen_assistants_to_none.py new file mode 100644 index 000000000..368f74c75 --- /dev/null +++ b/backend/alembic/versions/26b931506ecb_default_chosen_assistants_to_none.py @@ -0,0 +1,68 @@ +"""default chosen assistants to none + +Revision ID: 26b931506ecb +Revises: 2daa494a0851 +Create Date: 2024-11-12 13:23:29.858995 + +""" +from alembic import op +import sqlalchemy as sa +from sqlalchemy.dialects import postgresql + +# revision identifiers, used by Alembic. +revision = "26b931506ecb" +down_revision = "2daa494a0851" +branch_labels = None +depends_on = None + + +def upgrade() -> None: + op.add_column( + "user", sa.Column("chosen_assistants_new", postgresql.JSONB(), nullable=True) + ) + + op.execute( + """ + UPDATE "user" + SET chosen_assistants_new = + CASE + WHEN chosen_assistants = '[-2, -1, 0]' THEN NULL + ELSE chosen_assistants + END + """ + ) + + op.drop_column("user", "chosen_assistants") + + op.alter_column( + "user", "chosen_assistants_new", new_column_name="chosen_assistants" + ) + + +def downgrade() -> None: + op.add_column( + "user", + sa.Column( + "chosen_assistants_old", + postgresql.JSONB(), + nullable=False, + server_default="[-2, -1, 0]", + ), + ) + + op.execute( + """ + UPDATE "user" + SET chosen_assistants_old = + CASE + WHEN chosen_assistants IS NULL THEN '[-2, -1, 0]'::jsonb + ELSE chosen_assistants + END + """ + ) + + op.drop_column("user", "chosen_assistants") + + op.alter_column( + "user", "chosen_assistants_old", new_column_name="chosen_assistants" + ) diff --git a/backend/danswer/db/models.py b/backend/danswer/db/models.py index f0fd61b01..3fa74d450 100644 --- a/backend/danswer/db/models.py +++ b/backend/danswer/db/models.py @@ -126,8 +126,8 @@ class User(SQLAlchemyBaseUserTableUUID, Base): # if specified, controls the assistants that are shown to the user + their order # if not specified, all assistants are shown - chosen_assistants: Mapped[list[int]] = mapped_column( - postgresql.JSONB(), nullable=False, default=[-2, -1, 0] + chosen_assistants: Mapped[list[int] | None] = mapped_column( + postgresql.JSONB(), nullable=True, default=None ) visible_assistants: Mapped[list[int]] = mapped_column( postgresql.JSONB(), nullable=False, default=[] diff --git a/backend/danswer/db/persona.py b/backend/danswer/db/persona.py index f23b3f6d0..364c2ccc1 100644 --- a/backend/danswer/db/persona.py +++ b/backend/danswer/db/persona.py @@ -743,5 +743,4 @@ def delete_persona_by_name( ) db_session.execute(stmt) - db_session.commit() diff --git a/backend/danswer/server/manage/users.py b/backend/danswer/server/manage/users.py index 174dc5b55..46832e58f 100644 --- a/backend/danswer/server/manage/users.py +++ b/backend/danswer/server/manage/users.py @@ -630,31 +630,25 @@ def update_user_assistant_list( db_session.commit() -def update_assistant_list( +def update_assistant_visibility( preferences: UserPreferences, assistant_id: int, show: bool ) -> UserPreferences: visible_assistants = preferences.visible_assistants or [] hidden_assistants = preferences.hidden_assistants or [] - chosen_assistants = preferences.chosen_assistants or [] if show: if assistant_id not in visible_assistants: visible_assistants.append(assistant_id) if assistant_id in hidden_assistants: hidden_assistants.remove(assistant_id) - if assistant_id not in chosen_assistants: - chosen_assistants.append(assistant_id) else: if assistant_id in visible_assistants: visible_assistants.remove(assistant_id) if assistant_id not in hidden_assistants: hidden_assistants.append(assistant_id) - if assistant_id in chosen_assistants: - chosen_assistants.remove(assistant_id) preferences.visible_assistants = visible_assistants preferences.hidden_assistants = hidden_assistants - preferences.chosen_assistants = chosen_assistants return preferences @@ -670,15 +664,23 @@ def update_user_assistant_visibility( store = get_kv_store() no_auth_user = fetch_no_auth_user(store) preferences = no_auth_user.preferences - updated_preferences = update_assistant_list(preferences, assistant_id, show) + updated_preferences = update_assistant_visibility( + preferences, assistant_id, show + ) + if updated_preferences.chosen_assistants is not None: + updated_preferences.chosen_assistants.append(assistant_id) + set_no_auth_user_preferences(store, updated_preferences) return else: raise RuntimeError("This should never happen") user_preferences = UserInfo.from_model(user).preferences - updated_preferences = update_assistant_list(user_preferences, assistant_id, show) - + updated_preferences = update_assistant_visibility( + user_preferences, assistant_id, show + ) + if updated_preferences.chosen_assistants is not None: + updated_preferences.chosen_assistants.append(assistant_id) db_session.execute( update(User) .where(User.id == user.id) # type: ignore diff --git a/web/src/app/assistants/mine/AssistantsList.tsx b/web/src/app/assistants/mine/AssistantsList.tsx index 029097306..458d577e3 100644 --- a/web/src/app/assistants/mine/AssistantsList.tsx +++ b/web/src/app/assistants/mine/AssistantsList.tsx @@ -343,8 +343,6 @@ export function AssistantsList() { setCurrentlyVisibleAssistants(updatedAssistants); await updateUserAssistantList(updatedAssistants.map((a) => a.id)); - await refreshUser(); - await refreshAssistants(); } } diff --git a/web/src/app/chat/modal/configuration/AssistantsTab.tsx b/web/src/app/chat/modal/configuration/AssistantsTab.tsx index c62fab443..32c26ee17 100644 --- a/web/src/app/chat/modal/configuration/AssistantsTab.tsx +++ b/web/src/app/chat/modal/configuration/AssistantsTab.tsx @@ -61,8 +61,6 @@ export function AssistantsTab({ setAssistants(updatedAssistants); await updateUserAssistantList(updatedAssistants.map((a) => a.id)); - await refreshUser(); - await refreshAssistants(); } } diff --git a/web/src/components/context/AssistantsContext.tsx b/web/src/components/context/AssistantsContext.tsx index 73551cc93..87e498d16 100644 --- a/web/src/components/context/AssistantsContext.tsx +++ b/web/src/components/context/AssistantsContext.tsx @@ -47,7 +47,7 @@ export const AssistantsProvider: React.FC<{ const [assistants, setAssistants] = useState( initialAssistants || [] ); - const { user, isLoadingUser, refreshUser, isAdmin } = useUser(); + const { user, isLoadingUser, isAdmin } = useUser(); const [editablePersonas, setEditablePersonas] = useState([]); const [allAssistants, setAllAssistants] = useState([]); diff --git a/web/src/lib/assistants/utils.ts b/web/src/lib/assistants/utils.ts index 208c2ae98..7959dfdc4 100644 --- a/web/src/lib/assistants/utils.ts +++ b/web/src/lib/assistants/utils.ts @@ -35,16 +35,14 @@ export function classifyAssistants(user: User | null, assistants: Persona[]) { const isNotHidden = !user.preferences?.hidden_assistants?.includes( assistant.id ); - const isSelected = user.preferences?.chosen_assistants?.includes( - assistant.id - ); + const isBuiltIn = assistant.builtin_persona; const isDefault = assistant.is_default_persona; const isOwnedByUser = checkUserOwnsAssistant(user, assistant); const isShown = - (isVisible && isNotHidden && isSelected) || + (isVisible && isNotHidden) || (isNotHidden && (isBuiltIn || isDefault || isOwnedByUser)); return isShown; }); @@ -100,6 +98,7 @@ export function orderAssistantsForUser( const remainingAssistants = assistants.filter( (assistant) => !orderedAssistants.includes(assistant) ); + remainingAssistants.sort((a, b) => { const priorityA = a.display_priority ?? Number.MAX_SAFE_INTEGER; const priorityB = b.display_priority ?? Number.MAX_SAFE_INTEGER;