diff --git a/backend/onyx/auth/noauth_user.py b/backend/onyx/auth/noauth_user.py index 9a40e0cae49..e17694894e0 100644 --- a/backend/onyx/auth/noauth_user.py +++ b/backend/onyx/auth/noauth_user.py @@ -23,7 +23,6 @@ def load_no_auth_user_preferences(store: KeyValueStore) -> UserPreferences: preferences_data = cast( Mapping[str, Any], store.load(KV_NO_AUTH_USER_PREFERENCES_KEY) ) - print("preferences_data", preferences_data) return UserPreferences(**preferences_data) except KvKeyNotFoundError: return UserPreferences( diff --git a/backend/onyx/server/features/persona/api.py b/backend/onyx/server/features/persona/api.py index 684311ea7a8..caad8bdd4e5 100644 --- a/backend/onyx/server/features/persona/api.py +++ b/backend/onyx/server/features/persona/api.py @@ -7,6 +7,7 @@ from fastapi import Query from fastapi import UploadFile from pydantic import BaseModel +from sqlalchemy.exc import IntegrityError from sqlalchemy.orm import Session from onyx.auth.users import current_admin_user @@ -277,8 +278,14 @@ def create_label( _: User | None = Depends(current_user), ) -> PersonaLabelResponse: """Create a new assistant label""" - label_model = create_assistant_label(name=label.name, db_session=db) - return PersonaLabelResponse.from_model(label_model) + try: + label_model = create_assistant_label(name=label.name, db_session=db) + return PersonaLabelResponse.from_model(label_model) + except IntegrityError: + raise HTTPException( + status_code=400, + detail=f"Label with name '{label.name}' already exists. Please choose a different name.", + ) @admin_router.patch("/label/{label_id}") diff --git a/backend/onyx/server/manage/users.py b/backend/onyx/server/manage/users.py index 773cee01116..74438a9fd20 100644 --- a/backend/onyx/server/manage/users.py +++ b/backend/onyx/server/manage/users.py @@ -714,7 +714,6 @@ def update_user_pinned_assistants( store = get_kv_store() no_auth_user = fetch_no_auth_user(store) no_auth_user.preferences.pinned_assistants = ordered_assistant_ids - print("ordered_assistant_ids", ordered_assistant_ids) set_no_auth_user_preferences(store, no_auth_user.preferences) return else: diff --git a/web/next.config.js b/web/next.config.js index 1a8d7a53a6b..3de8bf2eb1b 100644 --- a/web/next.config.js +++ b/web/next.config.js @@ -22,6 +22,7 @@ const cspHeader = ` /** @type {import('next').NextConfig} */ const nextConfig = { + productionBrowserSourceMaps: true, output: "standalone", publicRuntimeConfig: { version, diff --git a/web/package-lock.json b/web/package-lock.json index 3d839aa71b5..c8cc83c2f7d 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -21,6 +21,7 @@ "@radix-ui/react-label": "^2.1.1", "@radix-ui/react-popover": "^1.1.2", "@radix-ui/react-radio-group": "^1.2.2", + "@radix-ui/react-scroll-area": "^1.2.2", "@radix-ui/react-select": "^2.1.2", "@radix-ui/react-separator": "^1.1.0", "@radix-ui/react-slot": "^1.1.0", @@ -4539,6 +4540,138 @@ } } }, + "node_modules/@radix-ui/react-scroll-area": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-scroll-area/-/react-scroll-area-1.2.2.tgz", + "integrity": "sha512-EFI1N/S3YxZEW/lJ/H1jY3njlvTd8tBmgKEn4GHi51+aMm94i6NmAJstsm5cu3yJwYqYc93gpCPm21FeAbFk6g==", + "license": "MIT", + "dependencies": { + "@radix-ui/number": "1.1.0", + "@radix-ui/primitive": "1.1.1", + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-direction": "1.1.0", + "@radix-ui/react-presence": "1.1.2", + "@radix-ui/react-primitive": "2.0.1", + "@radix-ui/react-use-callback-ref": "1.1.0", + "@radix-ui/react-use-layout-effect": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-scroll-area/node_modules/@radix-ui/primitive": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.1.tgz", + "integrity": "sha512-SJ31y+Q/zAyShtXJc8x83i9TYdbAfHZ++tUZnvjJJqFjzsdUnKsxPL6IEtBlxKkU7yzer//GQtZSV4GbldL3YA==", + "license": "MIT" + }, + "node_modules/@radix-ui/react-scroll-area/node_modules/@radix-ui/react-compose-refs": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.1.tgz", + "integrity": "sha512-Y9VzoRDSJtgFMUCoiZBDVo084VQ5hfpXxVE+NgkdNsjiDBByiImMZKKhxMwCbdHvhlENG6a833CbFkOQvTricw==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-scroll-area/node_modules/@radix-ui/react-context": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.1.tgz", + "integrity": "sha512-UASk9zi+crv9WteK/NU4PLvOoL3OuE6BWVKNF6hPRBtYBDXQ2u5iu3O59zUlJiTVvkyuycnqrztsHVJwcK9K+Q==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-scroll-area/node_modules/@radix-ui/react-presence": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.2.tgz", + "integrity": "sha512-18TFr80t5EVgL9x1SwF/YGtfG+l0BS0PRAlCWBDoBEiDQjeKgnNZRVJp/oVBl24sr3Gbfwc/Qpj4OcWTQMsAEg==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-use-layout-effect": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-scroll-area/node_modules/@radix-ui/react-primitive": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.1.tgz", + "integrity": "sha512-sHCWTtxwNn3L3fH8qAfnF3WbUZycW93SM1j3NFDzXBiz8D6F5UTTy8G1+WFEaiCdvCVRJWj6N2R4Xq6HdiHmDg==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-scroll-area/node_modules/@radix-ui/react-slot": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.1.tgz", + "integrity": "sha512-RApLLOcINYJA+dMVbOju7MYv1Mb2EBp2nH4HdDzXTSyaR5optlm6Otrz1euW3HbdOR8UmmFK06TD+A9frYWv+g==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-select": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/@radix-ui/react-select/-/react-select-2.1.2.tgz", diff --git a/web/package.json b/web/package.json index 0a1ce049ea4..0ff70547bcd 100644 --- a/web/package.json +++ b/web/package.json @@ -24,6 +24,7 @@ "@radix-ui/react-label": "^2.1.1", "@radix-ui/react-popover": "^1.1.2", "@radix-ui/react-radio-group": "^1.2.2", + "@radix-ui/react-scroll-area": "^1.2.2", "@radix-ui/react-select": "^2.1.2", "@radix-ui/react-separator": "^1.1.0", "@radix-ui/react-slot": "^1.1.0", diff --git a/web/src/app/admin/assistants/AssistantEditor.tsx b/web/src/app/admin/assistants/AssistantEditor.tsx index 9c4e8cbf017..22bd532f5b8 100644 --- a/web/src/app/admin/assistants/AssistantEditor.tsx +++ b/web/src/app/admin/assistants/AssistantEditor.tsx @@ -1,6 +1,6 @@ "use client"; -import React, { useCallback } from "react"; +import React from "react"; import { Option } from "@/components/Dropdown"; import { generateRandomIconShape } from "@/lib/assistantIconUtils"; import { CCPairBasicInfo, DocumentSet, User, UserGroup } from "@/lib/types"; @@ -35,7 +35,7 @@ import { import Link from "next/link"; import { useRouter } from "next/navigation"; import { useEffect, useMemo, useState } from "react"; -import { FiInfo, FiRefreshCcw, FiUsers } from "react-icons/fi"; +import { FiInfo } from "react-icons/fi"; import * as Yup from "yup"; import CollapsibleSection from "./CollapsibleSection"; import { SuccessfulPersonaUpdateRedirectType } from "./enums"; @@ -60,6 +60,7 @@ import { useAssistants } from "@/components/context/AssistantsContext"; import { debounce } from "lodash"; import { FullLLMProvider } from "../configuration/llm/interfaces"; import StarterMessagesList from "./StarterMessageList"; + import { Switch } from "@/components/ui/switch"; import { generateIdenticon } from "@/components/assistants/AssistantIcon"; import { BackButton } from "@/components/BackButton"; @@ -72,11 +73,13 @@ import { Option as DropdownOption, } from "@/components/Dropdown"; import { SourceChip } from "@/app/chat/input/ChatInputBar"; -import { TagIcon, UserIcon } from "lucide-react"; +import { TagIcon, UserIcon, XIcon } from "lucide-react"; import { LLMSelector } from "@/components/llm/LLMSelector"; import useSWR from "swr"; import { errorHandlingFetcher } from "@/lib/fetcher"; import { DeleteEntityModal } from "@/components/modals/DeleteEntityModal"; +import { DeletePersonaButton } from "./[id]/DeletePersonaButton"; +import Title from "@/components/ui/title"; function findSearchTool(tools: ToolSnapshot[]) { return tools.find((tool) => tool.in_code_tool_id === "SearchTool"); @@ -128,8 +131,8 @@ export function AssistantEditor({ const router = useRouter(); const { popup, setPopup } = usePopup(); - const { data, refreshLabels } = useLabels(); - const labels = data || []; + const { labels, refreshLabels, createLabel, updateLabel, deleteLabel } = + useLabels(); const colorOptions = [ "#FF6FBF", @@ -144,8 +147,6 @@ export function AssistantEditor({ const [showSearchTool, setShowSearchTool] = useState(false); const [showAdvancedOptions, setShowAdvancedOptions] = useState(false); - const [hasEditedStarterMessage, setHasEditedStarterMessage] = useState(false); - const [showPersonaLabel, setShowPersonaLabel] = useState(!admin); // state to persist across formik reformatting const [defautIconColor, _setDeafultIconColor] = useState( @@ -330,6 +331,10 @@ export function AssistantEditor({ })); }; + if (!labels) { + return <>>; + } + return (