diff --git a/surfsense_backend/app/config/__init__.py b/surfsense_backend/app/config/__init__.py index 724762854..448818e88 100644 --- a/surfsense_backend/app/config/__init__.py +++ b/surfsense_backend/app/config/__init__.py @@ -474,7 +474,8 @@ class Config: # Check if ffmpeg is installed if not is_ffmpeg_installed(): allow_static_ffmpeg = ( - os.getenv("SURFSENSE_ALLOW_STATIC_FFMPEG_DOWNLOAD", "TRUE").upper() == "TRUE" + os.getenv("SURFSENSE_ALLOW_STATIC_FFMPEG_DOWNLOAD", "TRUE").upper() + == "TRUE" ) if allow_static_ffmpeg: import static_ffmpeg diff --git a/surfsense_backend/tests/e2e/auth_mint.py b/surfsense_backend/tests/e2e/auth_mint.py index a80e68fc1..f489ed274 100644 --- a/surfsense_backend/tests/e2e/auth_mint.py +++ b/surfsense_backend/tests/e2e/auth_mint.py @@ -36,9 +36,7 @@ class MintResponse(BaseModel): def _expected_secret() -> str: - return os.environ.get( - "E2E_MINT_SECRET", "local-e2e-mint-secret-not-for-production" - ) + return os.environ.get("E2E_MINT_SECRET", "local-e2e-mint-secret-not-for-production") router = APIRouter(prefix="/__e2e__", tags=["__e2e__"]) diff --git a/surfsense_backend/tests/e2e/fakes/docling_service.py b/surfsense_backend/tests/e2e/fakes/docling_service.py index 2486f5db6..9dd09d603 100644 --- a/surfsense_backend/tests/e2e/fakes/docling_service.py +++ b/surfsense_backend/tests/e2e/fakes/docling_service.py @@ -92,7 +92,9 @@ async def fake_process_document( # Empty fallback so the indexing pipeline does not error out on # an unexpected payload. A failing canary assertion is a much # clearer failure mode than a hard parser exception. - content = f"# {display_name}\n\n(empty docling fake — no text-show operators found)\n" + content = ( + f"# {display_name}\n\n(empty docling fake — no text-show operators found)\n" + ) logger.info( "[fake-docling] returning %d chars for %s", diff --git a/surfsense_backend/tests/e2e/run_backend.py b/surfsense_backend/tests/e2e/run_backend.py index d0c734751..5a787ac52 100644 --- a/surfsense_backend/tests/e2e/run_backend.py +++ b/surfsense_backend/tests/e2e/run_backend.py @@ -164,9 +164,7 @@ def _install_synthetic_global_llm_config() -> None: import shutil src = os.path.join(_THIS_DIR, "fixtures", "global_llm_config.yaml") - dst = os.path.join( - _BACKEND_ROOT, "app", "config", "global_llm_config.yaml" - ) + dst = os.path.join(_BACKEND_ROOT, "app", "config", "global_llm_config.yaml") if not os.path.exists(src): raise RuntimeError( diff --git a/surfsense_backend/tests/e2e/run_celery.py b/surfsense_backend/tests/e2e/run_celery.py index fd6cc88cf..e4091d689 100644 --- a/surfsense_backend/tests/e2e/run_celery.py +++ b/surfsense_backend/tests/e2e/run_celery.py @@ -142,9 +142,7 @@ def _install_synthetic_global_llm_config() -> None: import shutil src = os.path.join(_THIS_DIR, "fixtures", "global_llm_config.yaml") - dst = os.path.join( - _BACKEND_ROOT, "app", "config", "global_llm_config.yaml" - ) + dst = os.path.join(_BACKEND_ROOT, "app", "config", "global_llm_config.yaml") if not os.path.exists(src): raise RuntimeError( diff --git a/surfsense_web/app/dashboard/[search_space_id]/new-chat/[[...chat_id]]/page.tsx b/surfsense_web/app/dashboard/[search_space_id]/new-chat/[[...chat_id]]/page.tsx index c431ab304..0ebd8dc9a 100644 --- a/surfsense_web/app/dashboard/[search_space_id]/new-chat/[[...chat_id]]/page.tsx +++ b/surfsense_web/app/dashboard/[search_space_id]/new-chat/[[...chat_id]]/page.tsx @@ -208,7 +208,10 @@ const MentionedDocumentInfoSchema = z.object({ id: z.number(), title: z.string(), document_type: z.string(), - kind: z.union([z.literal("doc"), z.literal("folder")]).optional().default("doc"), + kind: z + .union([z.literal("doc"), z.literal("folder")]) + .optional() + .default("doc"), }); const MentionedDocumentsPartSchema = z.object({ @@ -1029,9 +1032,7 @@ export default function NewChatPage() { mentioned_surfsense_doc_ids: hasSurfsenseDocIds ? mentionedDocumentIds.surfsense_doc_ids : undefined, - mentioned_folder_ids: hasFolderIds - ? mentionedDocumentIds.folder_ids - : undefined, + mentioned_folder_ids: hasFolderIds ? mentionedDocumentIds.folder_ids : undefined, // Full mention metadata (docs + folders, with // ``kind`` discriminator) so the BE can embed a // ``mentioned-documents`` ContentPart on the @@ -1900,12 +1901,10 @@ export default function NewChatPage() { filesystem_mode: selection.filesystem_mode, client_platform: selection.client_platform, local_filesystem_mounts: selection.local_filesystem_mounts, - mentioned_document_ids: - regenerateDocIds.length > 0 ? regenerateDocIds : undefined, + mentioned_document_ids: regenerateDocIds.length > 0 ? regenerateDocIds : undefined, mentioned_surfsense_doc_ids: regenerateSurfsenseDocIds.length > 0 ? regenerateSurfsenseDocIds : undefined, - mentioned_folder_ids: - regenerateFolderIds.length > 0 ? regenerateFolderIds : undefined, + mentioned_folder_ids: regenerateFolderIds.length > 0 ? regenerateFolderIds : undefined, // Full mention metadata for the regenerate-specific // source list. Only meaningful for edit (the BE only // re-persists a user row when ``user_query`` is set); diff --git a/surfsense_web/atoms/chat/mentioned-documents.atom.ts b/surfsense_web/atoms/chat/mentioned-documents.atom.ts index eafdaf87e..9163960f4 100644 --- a/surfsense_web/atoms/chat/mentioned-documents.atom.ts +++ b/surfsense_web/atoms/chat/mentioned-documents.atom.ts @@ -97,9 +97,7 @@ export const mentionedDocumentIdsAtom = atom((get) => { surfsense_doc_ids: docs .filter((doc) => doc.document_type === "SURFSENSE_DOCS") .map((doc) => doc.id), - document_ids: docs - .filter((doc) => doc.document_type !== "SURFSENSE_DOCS") - .map((doc) => doc.id), + document_ids: docs.filter((doc) => doc.document_type !== "SURFSENSE_DOCS").map((doc) => doc.id), folder_ids: folders.map((f) => f.id), }; }); diff --git a/surfsense_web/components/assistant-ui/inline-mention-editor.tsx b/surfsense_web/components/assistant-ui/inline-mention-editor.tsx index e12556486..c7893b6ac 100644 --- a/surfsense_web/components/assistant-ui/inline-mention-editor.tsx +++ b/surfsense_web/components/assistant-ui/inline-mention-editor.tsx @@ -47,10 +47,7 @@ export interface InlineMentionEditorRef { setText: (text: string) => void; getText: () => string; getMentionedDocuments: () => MentionedDocument[]; - insertMentionChip: ( - mention: MentionChipInput, - options?: { removeTriggerText?: boolean } - ) => void; + insertMentionChip: (mention: MentionChipInput, options?: { removeTriggerText?: boolean }) => void; /** * @deprecated Use ``insertMentionChip``. Kept for one transition * cycle so we don't break ad-hoc callers; prefer the new name. @@ -364,8 +361,7 @@ export const InlineMentionEditor = forwardRef - ) : ( - - ); + const icon = isFolder ? : ; const handleClick = useCallback( (event: React.MouseEvent) => { diff --git a/surfsense_web/components/assistant-ui/user-message.tsx b/surfsense_web/components/assistant-ui/user-message.tsx index b09aa7680..708cefbc0 100644 --- a/surfsense_web/components/assistant-ui/user-message.tsx +++ b/surfsense_web/components/assistant-ui/user-message.tsx @@ -111,11 +111,7 @@ const UserTextPart: FC = () => { icon={icon} label={segment.doc.title} tooltip={isFolder ? `Folder: ${segment.doc.title}` : segment.doc.title} - onClick={ - isFolder - ? undefined - : () => handleOpenDoc(segment.doc.id, segment.doc.title) - } + onClick={isFolder ? undefined : () => handleOpenDoc(segment.doc.id, segment.doc.title)} className="mx-0.5" /> ); diff --git a/surfsense_web/components/editor/plate-editor.tsx b/surfsense_web/components/editor/plate-editor.tsx index 51ad7d700..77845ad2a 100644 --- a/surfsense_web/components/editor/plate-editor.tsx +++ b/surfsense_web/components/editor/plate-editor.tsx @@ -170,16 +170,10 @@ export function PlateEditor({ : markdown ? (editor) => { if (!enableCitations) { - return safeDeserializeMarkdown( - editor, - escapeMdxExpressions(markdown) - ) as Value; + return safeDeserializeMarkdown(editor, escapeMdxExpressions(markdown)) as Value; } const { content: rewritten, urlMap } = preprocessCitationMarkdown(markdown); - const value = safeDeserializeMarkdown( - editor, - escapeMdxExpressions(rewritten) - ); + const value = safeDeserializeMarkdown(editor, escapeMdxExpressions(rewritten)); return injectCitationNodes(value, urlMap) as Value; } : undefined, @@ -203,10 +197,7 @@ export function PlateEditor({ let newValue: Descendant[]; if (enableCitations) { const { content: rewritten, urlMap } = preprocessCitationMarkdown(markdown); - const deserialized = safeDeserializeMarkdown( - editor, - escapeMdxExpressions(rewritten) - ); + const deserialized = safeDeserializeMarkdown(editor, escapeMdxExpressions(rewritten)); newValue = injectCitationNodes(deserialized, urlMap); } else { newValue = safeDeserializeMarkdown(editor, escapeMdxExpressions(markdown)); diff --git a/surfsense_web/components/editor/utils/safe-deserialize.ts b/surfsense_web/components/editor/utils/safe-deserialize.ts index e359a7791..8f3e6275b 100644 --- a/surfsense_web/components/editor/utils/safe-deserialize.ts +++ b/surfsense_web/components/editor/utils/safe-deserialize.ts @@ -49,10 +49,7 @@ export function safeDeserializeMarkdown( return api.deserialize(markdown, { remarkPlugins: STRICT_PLUGINS }) as Descendant[]; } catch (mdxError) { if (process.env.NODE_ENV !== "production") { - console.warn( - "[plate-editor] MDX parse failed, retrying without remark-mdx:", - mdxError - ); + console.warn("[plate-editor] MDX parse failed, retrying without remark-mdx:", mdxError); } try { return api.deserialize(markdown, { remarkPlugins: LENIENT_PLUGINS }) as Descendant[]; diff --git a/surfsense_web/components/layout/ui/sidebar/DocumentsSidebar.tsx b/surfsense_web/components/layout/ui/sidebar/DocumentsSidebar.tsx index 958941928..3ecf046bb 100644 --- a/surfsense_web/components/layout/ui/sidebar/DocumentsSidebar.tsx +++ b/surfsense_web/components/layout/ui/sidebar/DocumentsSidebar.tsx @@ -24,10 +24,7 @@ import type React from "react"; import { useCallback, useEffect, useMemo, useRef, useState } from "react"; import { toast } from "sonner"; import { agentFlagsAtom } from "@/atoms/agent/agent-flags-query.atom"; -import { - makeFolderMention, - mentionedDocumentsAtom, -} from "@/atoms/chat/mentioned-documents.atom"; +import { makeFolderMention, mentionedDocumentsAtom } from "@/atoms/chat/mentioned-documents.atom"; import { connectorDialogOpenAtom } from "@/atoms/connector-dialog/connector-dialog.atoms"; import { connectorsAtom } from "@/atoms/connectors/connector-query.atoms"; import { deleteDocumentMutationAtom } from "@/atoms/documents/document-mutation.atoms"; diff --git a/surfsense_web/components/new-chat/document-mention-picker.tsx b/surfsense_web/components/new-chat/document-mention-picker.tsx index 0881b11b6..0d68c8df8 100644 --- a/surfsense_web/components/new-chat/document-mention-picker.tsx +++ b/surfsense_web/components/new-chat/document-mention-picker.tsx @@ -301,8 +301,7 @@ export const DocumentMentionPicker = forwardRef< // folder entries lift the existing kind-aware key so the same // matchers used by the chip atom apply unchanged. const selectedKeys = useMemo( - () => - new Set(initialSelectedDocuments.map((d) => getMentionDocKey(d))), + () => new Set(initialSelectedDocuments.map((d) => getMentionDocKey(d))), [initialSelectedDocuments] ); @@ -583,9 +582,7 @@ export const DocumentMentionPicker = forwardRef< {(surfsenseDocsList.length > 0 || userDocsList.length > 0) && (
)} -
- Folders -
+
Folders
{folderMentions.map((folder) => { const folderKey = getMentionDocKey(folder); const isAlreadySelected = selectedKeys.has(folderKey); diff --git a/surfsense_web/playwright.config.ts b/surfsense_web/playwright.config.ts index eb287635d..ef066a9be 100644 --- a/surfsense_web/playwright.config.ts +++ b/surfsense_web/playwright.config.ts @@ -59,19 +59,15 @@ export default defineConfig({ ? undefined : { // Local stays on webpack dev (Turbopack caused stale-lock panics in E2E). - command: process.env.CI - ? "pnpm build && pnpm start" - : "pnpm exec next dev", + command: process.env.CI ? "pnpm build && pnpm start" : "pnpm exec next dev", url: `http://localhost:${PORT}`, reuseExistingServer: !process.env.CI, timeout: process.env.CI ? 300_000 : 180_000, stdout: "pipe", - stderr: "pipe", + stderr: "pipe", env: { - NEXT_PUBLIC_FASTAPI_BACKEND_URL: - process.env.NEXT_PUBLIC_FASTAPI_BACKEND_URL, - NEXT_PUBLIC_FASTAPI_BACKEND_AUTH_TYPE: - process.env.NEXT_PUBLIC_FASTAPI_BACKEND_AUTH_TYPE, + NEXT_PUBLIC_FASTAPI_BACKEND_URL: process.env.NEXT_PUBLIC_FASTAPI_BACKEND_URL, + NEXT_PUBLIC_FASTAPI_BACKEND_AUTH_TYPE: process.env.NEXT_PUBLIC_FASTAPI_BACKEND_AUTH_TYPE, }, }, }); diff --git a/surfsense_web/tests/helpers/api/auth.ts b/surfsense_web/tests/helpers/api/auth.ts index 2071a80f4..6492b09ba 100644 --- a/surfsense_web/tests/helpers/api/auth.ts +++ b/surfsense_web/tests/helpers/api/auth.ts @@ -13,8 +13,7 @@ export const BACKEND_URL = process.env.NEXT_PUBLIC_FASTAPI_BACKEND_URL || "http: const TEST_USER_EMAIL = process.env.PLAYWRIGHT_TEST_EMAIL || "e2e-test@surfsense.net"; const TEST_USER_PASSWORD = process.env.PLAYWRIGHT_TEST_PASSWORD || "E2eTestPassword123!"; -const E2E_MINT_SECRET = - process.env.E2E_MINT_SECRET || "local-e2e-mint-secret-not-for-production"; +const E2E_MINT_SECRET = process.env.E2E_MINT_SECRET || "local-e2e-mint-secret-not-for-production"; /** * Mints a JWT for the seeded e2e user via the test-only endpoint mounted