diff --git a/backend/danswer/db/persona.py b/backend/danswer/db/persona.py index f23b3f6d071..22049ec8163 100644 --- a/backend/danswer/db/persona.py +++ b/backend/danswer/db/persona.py @@ -390,6 +390,9 @@ def upsert_prompt( return prompt +# NOTE: This operation cannot update persona configuration options that +# are core to the persona, such as its display priority and +# whether or not the assistant is a built-in / default assistant def upsert_persona( user: User | None, name: str, @@ -457,7 +460,7 @@ def upsert_persona( validate_persona_tools(tools) if persona: - if not builtin_persona and persona.builtin_persona: + if persona.builtin_persona and not builtin_persona: raise ValueError("Cannot update builtin persona with non-builtin.") # this checks if the user has permission to edit the persona @@ -473,7 +476,6 @@ def upsert_persona( persona.llm_relevance_filter = llm_relevance_filter persona.llm_filter_extraction = llm_filter_extraction persona.recency_bias = recency_bias - persona.builtin_persona = builtin_persona persona.llm_model_provider_override = llm_model_provider_override persona.llm_model_version_override = llm_model_version_override persona.starter_messages = starter_messages @@ -483,7 +485,6 @@ def upsert_persona( persona.icon_shape = icon_shape if remove_image or uploaded_image_id: persona.uploaded_image_id = uploaded_image_id - persona.display_priority = display_priority persona.is_visible = is_visible persona.search_start_date = search_start_date persona.is_default_persona = is_default_persona diff --git a/backend/danswer/server/features/persona/api.py b/backend/danswer/server/features/persona/api.py index 1e0e84a5896..8a084dbb3b2 100644 --- a/backend/danswer/server/features/persona/api.py +++ b/backend/danswer/server/features/persona/api.py @@ -168,6 +168,9 @@ def create_persona( ) +# NOTE: This endpoint cannot update persona configuration options that +# are core to the persona, such as its display priority and +# whether or not the assistant is a built-in / default assistant @basic_router.patch("/{persona_id}") def update_persona( persona_id: int, diff --git a/backend/danswer/server/manage/users.py b/backend/danswer/server/manage/users.py index 174dc5b55c9..bcb0ca013a4 100644 --- a/backend/danswer/server/manage/users.py +++ b/backend/danswer/server/manage/users.py @@ -614,7 +614,6 @@ def update_user_assistant_list( if user is None: if AUTH_TYPE == AuthType.DISABLED: store = get_kv_store() - no_auth_user = fetch_no_auth_user(store) no_auth_user.preferences.chosen_assistants = request.chosen_assistants set_no_auth_user_preferences(store, no_auth_user.preferences) diff --git a/web/src/app/admin/assistants/AssistantEditor.tsx b/web/src/app/admin/assistants/AssistantEditor.tsx index a4ed2fea2a1..0108023a29d 100644 --- a/web/src/app/admin/assistants/AssistantEditor.tsx +++ b/web/src/app/admin/assistants/AssistantEditor.tsx @@ -359,6 +359,7 @@ export function AssistantEditor({ if (!promptResponse.ok) { error = await promptResponse.text(); } + if (!personaResponse) { error = "Failed to create Assistant - no response received"; } else if (!personaResponse.ok) { diff --git a/web/src/app/admin/assistants/lib.ts b/web/src/app/admin/assistants/lib.ts index 9be6dbae834..8b7e6306b5b 100644 --- a/web/src/app/admin/assistants/lib.ts +++ b/web/src/app/admin/assistants/lib.ts @@ -219,9 +219,29 @@ export async function updatePersona( ): Promise<[Response, Response | null]> { const { id, existingPromptId } = personaUpdateRequest; - // first update prompt + let fileId = null; + if (personaUpdateRequest.uploaded_image) { + fileId = await uploadFile(personaUpdateRequest.uploaded_image); + if (!fileId) { + return [new Response(null, { status: 400 }), null]; + } + } + + const updatePersonaResponse = await fetch(`/api/persona/${id}`, { + method: "PATCH", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify( + buildPersonaAPIBody(personaUpdateRequest, existingPromptId ?? 0, fileId) + ), + }); + + if (!updatePersonaResponse.ok) { + return [updatePersonaResponse, null]; + } + let promptResponse; - let promptId; if (existingPromptId !== undefined) { promptResponse = await updatePrompt({ promptId: existingPromptId, @@ -230,7 +250,6 @@ export async function updatePersona( taskPrompt: personaUpdateRequest.task_prompt, includeCitations: personaUpdateRequest.include_citations, }); - promptId = existingPromptId; } else { promptResponse = await createPrompt({ personaName: personaUpdateRequest.name, @@ -238,30 +257,8 @@ export async function updatePersona( taskPrompt: personaUpdateRequest.task_prompt, includeCitations: personaUpdateRequest.include_citations, }); - promptId = promptResponse.ok ? (await promptResponse.json()).id : null; } - let fileId = null; - if (personaUpdateRequest.uploaded_image) { - fileId = await uploadFile(personaUpdateRequest.uploaded_image); - if (!fileId) { - return [promptResponse, null]; - } - } - - const updatePersonaResponse = - promptResponse.ok && promptId - ? await fetch(`/api/persona/${id}`, { - method: "PATCH", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify( - buildPersonaAPIBody(personaUpdateRequest, promptId, fileId) - ), - }) - : null; - return [promptResponse, updatePersonaResponse]; } diff --git a/web/src/app/assistants/gallery/AssistantsGallery.tsx b/web/src/app/assistants/gallery/AssistantsGallery.tsx index cf5b81a9a28..18feacc9661 100644 --- a/web/src/app/assistants/gallery/AssistantsGallery.tsx +++ b/web/src/app/assistants/gallery/AssistantsGallery.tsx @@ -18,11 +18,13 @@ import { classifyAssistants } from "@/lib/assistants/utils"; import { useAssistants } from "@/components/context/AssistantsContext"; import { useUser } from "@/components/user/UserProvider"; export function AssistantGalleryCard({ + onlyAssistant, assistant, user, setPopup, selectedAssistant, }: { + onlyAssistant: boolean; assistant: Persona; user: User | null; setPopup: (popup: PopupSpec) => void; @@ -66,10 +68,7 @@ export function AssistantGalleryCard({ " icon={FiMinus} onClick={async () => { - if ( - user.preferences?.chosen_assistants && - user.preferences?.chosen_assistants.length === 1 - ) { + if (onlyAssistant) { setPopup({ message: `Cannot remove "${assistant.name}" - you must have at least one assistant.`, type: "error", @@ -268,6 +267,7 @@ export function AssistantsGallery() { > {defaultAssistants.map((assistant) => ( {nonDefaultAssistants.map((assistant) => ( >; setPopup: (popupSpec: PopupSpec | null) => void; isDragging?: boolean; + onlyAssistant: boolean; }) { const { refreshUser } = useUser(); const router = useRouter(); const [showSharingModal, setShowSharingModal] = useState(false); const isOwnedByUser = checkUserOwnsAssistant(user, assistant); - const currentChosenAssistants = user?.preferences - ?.chosen_assistants as number[]; return ( <> @@ -192,13 +192,14 @@ function AssistantListItem({ key="remove" className="flex items-center gap-x-2 px-4 py-2 hover:bg-gray-100 w-full text-left" onClick={async () => { - if (currentChosenAssistants?.length === 1) { + if (onlyAssistant) { setPopup({ message: `Cannot remove "${assistant.name}" - you must have at least one assistant.`, type: "error", }); return; } + const success = await removeAssistantFromList( assistant.id ); @@ -434,6 +435,7 @@ export function AssistantsList() {
{currentlyVisibleAssistants.map((assistant, index) => ( {ownedButHiddenAssistants.map((assistant, index) => (