diff --git a/surfsense_backend/app/agents/new_chat/tools/knowledge_base.py b/surfsense_backend/app/agents/new_chat/tools/knowledge_base.py index bdd368a32..cf34e3e85 100644 --- a/surfsense_backend/app/agents/new_chat/tools/knowledge_base.py +++ b/surfsense_backend/app/agents/new_chat/tools/knowledge_base.py @@ -271,7 +271,7 @@ def format_documents_for_context(documents: list[dict[str, Any]]) -> str: # Live search connectors whose results should be cited by URL rather than # a numeric chunk_id (the numeric IDs are meaningless auto-incremented counters). - _LIVE_SEARCH_CONNECTORS = { + live_search_connectors = { "TAVILY_API", "SEARXNG_API", "LINKUP_API", @@ -282,7 +282,7 @@ def format_documents_for_context(documents: list[dict[str, Any]]) -> str: parts: list[str] = [] for g in grouped.values(): metadata_json = json.dumps(g["metadata"], ensure_ascii=False) - is_live_search = g["document_type"] in _LIVE_SEARCH_CONNECTORS + is_live_search = g["document_type"] in live_search_connectors parts.append("") parts.append("") diff --git a/surfsense_backend/app/connectors/webcrawler_connector.py b/surfsense_backend/app/connectors/webcrawler_connector.py index 70272976e..1b866dfc4 100644 --- a/surfsense_backend/app/connectors/webcrawler_connector.py +++ b/surfsense_backend/app/connectors/webcrawler_connector.py @@ -89,9 +89,7 @@ class WebCrawlerConnector: return await self._crawl_with_firecrawl(url, formats), None except Exception as exc: errors.append(f"Firecrawl: {exc!s}") - logger.warning( - f"[webcrawler] Firecrawl failed for {url}: {exc!s}" - ) + logger.warning(f"[webcrawler] Firecrawl failed for {url}: {exc!s}") # --- 2. HTTP + Trafilatura (no subprocess required) --- try: diff --git a/surfsense_web/app/(home)/announcements/page.tsx b/surfsense_web/app/(home)/announcements/page.tsx index 7be00a533..bfc883dfc 100644 --- a/surfsense_web/app/(home)/announcements/page.tsx +++ b/surfsense_web/app/(home)/announcements/page.tsx @@ -69,11 +69,7 @@ const categoryConfig: Record< // Announcement card // --------------------------------------------------------------------------- -function AnnouncementCard({ - announcement, -}: { - announcement: AnnouncementWithState; -}) { +function AnnouncementCard({ announcement }: { announcement: AnnouncementWithState }) { const config = categoryConfig[announcement.category] ?? categoryConfig.info; const Icon = config.icon; @@ -179,10 +175,7 @@ export default function AnnouncementsPage() { ) : (
{announcements.map((announcement) => ( - + ))}
)} diff --git a/surfsense_web/components/announcements/AnnouncementToastProvider.tsx b/surfsense_web/components/announcements/AnnouncementToastProvider.tsx index 591c3b875..3ae6bf233 100644 --- a/surfsense_web/components/announcements/AnnouncementToastProvider.tsx +++ b/surfsense_web/components/announcements/AnnouncementToastProvider.tsx @@ -69,7 +69,7 @@ export function AnnouncementToastProvider() { const authed = isAuthenticated(); const active = getActiveAnnouncements(announcements, authed); const importantUntoasted = active.filter( - (a) => a.isImportant && !isAnnouncementToasted(a.id), + (a) => a.isImportant && !isAnnouncementToasted(a.id) ); for (let i = 0; i < importantUntoasted.length; i++) { diff --git a/surfsense_web/components/assistant-ui/connector-popup/connector-configs/views/connector-connect-view.tsx b/surfsense_web/components/assistant-ui/connector-popup/connector-configs/views/connector-connect-view.tsx index e8d811d9f..423819363 100644 --- a/surfsense_web/components/assistant-ui/connector-popup/connector-configs/views/connector-connect-view.tsx +++ b/surfsense_web/components/assistant-ui/connector-popup/connector-configs/views/connector-connect-view.tsx @@ -64,9 +64,7 @@ export const ConnectorConnectView: FC = ({ const formId = FORM_ID_MAP[connectorType]; const root = formContainerRef.current; const mappedForm = - root && formId - ? (root.querySelector(`[id="${formId}"]`) as HTMLFormElement | null) - : null; + root && formId ? (root.querySelector(`[id="${formId}"]`) as HTMLFormElement | null) : null; // Fallback to currently rendered form to avoid silent no-op // when a connector type or form id mapping drifts. const fallbackForm = root?.querySelector("form") as HTMLFormElement | null; diff --git a/surfsense_web/components/assistant-ui/inline-citation.tsx b/surfsense_web/components/assistant-ui/inline-citation.tsx index d5dff68c1..af3edc760 100644 --- a/surfsense_web/components/assistant-ui/inline-citation.tsx +++ b/surfsense_web/components/assistant-ui/inline-citation.tsx @@ -1,8 +1,8 @@ "use client"; +import { ExternalLink } from "lucide-react"; import type { FC } from "react"; import { useState } from "react"; -import { ExternalLink } from "lucide-react"; import { SourceDetailPanel } from "@/components/new-chat/source-detail-panel"; interface InlineCitationProps { @@ -14,10 +14,7 @@ interface InlineCitationProps { * Inline citation for knowledge-base chunks (numeric chunk IDs). * Renders a clickable badge showing the actual chunk ID that opens the SourceDetailPanel. */ -export const InlineCitation: FC = ({ - chunkId, - isDocsChunk = false, -}) => { +export const InlineCitation: FC = ({ chunkId, isDocsChunk = false }) => { const [isOpen, setIsOpen] = useState(false); return ( diff --git a/surfsense_web/components/assistant-ui/markdown-text.tsx b/surfsense_web/components/assistant-ui/markdown-text.tsx index e593f429c..10ce85c5a 100644 --- a/surfsense_web/components/assistant-ui/markdown-text.tsx +++ b/surfsense_web/components/assistant-ui/markdown-text.tsx @@ -36,7 +36,7 @@ function preprocessMarkdown(content: string): string { _pendingUrlCitations = new Map(); _urlCiteIdx = 0; content = content.replace( - /[[【]\u200B?citation:\s*(https?:\/\/[^\]\】\u200B]+)\s*\u200B?[\]】]/g, + /[[【]\u200B?citation:\s*(https?:\/\/[^\]】\u200B]+)\s*\u200B?[\]】]/g, (_, url) => { const key = `urlcite${_urlCiteIdx++}`; _pendingUrlCitations.set(key, url.trim()); @@ -73,7 +73,7 @@ function preprocessMarkdown(content: string): string { // URL-based IDs from live web search, or urlciteN placeholders from preprocess. // Also matches Chinese brackets 【】 and handles zero-width spaces that LLM sometimes inserts. const CITATION_REGEX = - /[[【]\u200B?citation:\s*(https?:\/\/[^\]\】\u200B]+|urlcite\d+|(?:doc-)?\d+(?:\s*,\s*(?:doc-)?\d+)*)\s*\u200B?[\]】]/g; + /[[【]\u200B?citation:\s*(https?:\/\/[^\]】\u200B]+|urlcite\d+|(?:doc-)?\d+(?:\s*,\s*(?:doc-)?\d+)*)\s*\u200B?[\]】]/g; /** * Parses text and replaces [citation:XXX] patterns with citation components. @@ -100,16 +100,12 @@ function parseTextWithCitations(text: string): ReactNode[] { const captured = match[1]; if (captured.startsWith("http://") || captured.startsWith("https://")) { - parts.push( - - ); + parts.push(); instanceIndex++; } else if (captured.startsWith("urlcite")) { const url = _pendingUrlCitations.get(captured); if (url) { - parts.push( - - ); + parts.push(); } instanceIndex++; } else { diff --git a/surfsense_web/components/editor/plate-editor.tsx b/surfsense_web/components/editor/plate-editor.tsx index a0c316d88..688b481f1 100644 --- a/surfsense_web/components/editor/plate-editor.tsx +++ b/surfsense_web/components/editor/plate-editor.tsx @@ -1,16 +1,15 @@ "use client"; -import { useEffect, useMemo, useRef } from "react"; import { MarkdownPlugin, remarkMdx } from "@platejs/markdown"; import type { AnyPluginConfig } from "platejs"; import { createPlatePlugin, Key, Plate, usePlateEditor } from "platejs/react"; +import { useEffect, useMemo, useRef } from "react"; import remarkGfm from "remark-gfm"; import remarkMath from "remark-math"; - -import { type EditorPreset, presetMap } from "@/components/editor/presets"; -import { Editor, EditorContainer } from "@/components/ui/editor"; -import { escapeMdxExpressions } from "@/components/editor/utils/escape-mdx"; import { EditorSaveContext } from "@/components/editor/editor-save-context"; +import { type EditorPreset, presetMap } from "@/components/editor/presets"; +import { escapeMdxExpressions } from "@/components/editor/utils/escape-mdx"; +import { Editor, EditorContainer } from "@/components/ui/editor"; export interface PlateEditorProps { /** Markdown string to load as initial content */ diff --git a/surfsense_web/components/editor/plugins/autoformat-kit.tsx b/surfsense_web/components/editor/plugins/autoformat-kit.tsx index a145fbb94..98f5a128c 100644 --- a/surfsense_web/components/editor/plugins/autoformat-kit.tsx +++ b/surfsense_web/components/editor/plugins/autoformat-kit.tsx @@ -3,11 +3,11 @@ import type { AutoformatRule } from "@platejs/autoformat"; import { + AutoformatPlugin, autoformatArrow, autoformatLegal, autoformatLegalHtml, autoformatMath, - AutoformatPlugin, autoformatPunctuation, autoformatSmartQuotes, } from "@platejs/autoformat"; diff --git a/surfsense_web/components/editor/plugins/dnd-kit.tsx b/surfsense_web/components/editor/plugins/dnd-kit.tsx index 0d02c855e..63920353d 100644 --- a/surfsense_web/components/editor/plugins/dnd-kit.tsx +++ b/surfsense_web/components/editor/plugins/dnd-kit.tsx @@ -1,10 +1,9 @@ "use client"; +import { DndPlugin } from "@platejs/dnd"; import { DndProvider } from "react-dnd"; import { HTML5Backend } from "react-dnd-html5-backend"; -import { DndPlugin } from "@platejs/dnd"; - import { BlockDraggable } from "@/components/ui/block-draggable"; export const DndKit = [ diff --git a/surfsense_web/components/editor/transforms.ts b/surfsense_web/components/editor/transforms.ts index 5f74c9673..5590e4a50 100644 --- a/surfsense_web/components/editor/transforms.ts +++ b/surfsense_web/components/editor/transforms.ts @@ -1,13 +1,12 @@ "use client"; -import type { PlateEditor } from "platejs/react"; - import { insertCallout } from "@platejs/callout"; import { insertCodeBlock, toggleCodeBlock } from "@platejs/code-block"; import { triggerFloatingLink } from "@platejs/link/react"; import { insertInlineEquation } from "@platejs/math"; import { TablePlugin } from "@platejs/table/react"; -import { type NodeEntry, type Path, type TElement, KEYS, PathApi } from "platejs"; +import { KEYS, type NodeEntry, type Path, PathApi, type TElement } from "platejs"; +import type { PlateEditor } from "platejs/react"; const insertList = (editor: PlateEditor, type: string) => { editor.tf.insertNodes( diff --git a/surfsense_web/components/providers/PostHogIdentify.tsx b/surfsense_web/components/providers/PostHogIdentify.tsx index cb11d6fe7..57a7766b8 100644 --- a/surfsense_web/components/providers/PostHogIdentify.tsx +++ b/surfsense_web/components/providers/PostHogIdentify.tsx @@ -26,12 +26,12 @@ export function PostHogIdentify() { // Only identify if this is a new user or different from previous if (previousUserIdRef.current !== userId) { - identifyUser(userId, { - email: user.email, - name: user.display_name, - is_superuser: user.is_superuser, - is_verified: user.is_verified, - }); + identifyUser(userId, { + email: user.email, + name: user.display_name, + is_superuser: user.is_superuser, + is_verified: user.is_verified, + }); previousUserIdRef.current = userId; } } diff --git a/surfsense_web/components/shared/llm-config-form.tsx b/surfsense_web/components/shared/llm-config-form.tsx index dd3b71ce1..648457919 100644 --- a/surfsense_web/components/shared/llm-config-form.tsx +++ b/surfsense_web/components/shared/llm-config-form.tsx @@ -300,58 +300,58 @@ export function LLMConfigForm({ - - - - -
- {field.value ? `Using: "${field.value}"` : "Type your model name"} -
-
- {availableModels.length > 0 && ( - - {availableModels - .filter( - (model) => - !field.value || - model.value.toLowerCase().includes(field.value.toLowerCase()) || - model.label.toLowerCase().includes(field.value.toLowerCase()) - ) - .slice(0, 50) - .map((model) => ( - { - field.onChange(value); - setModelComboboxOpen(false); - }} - className="py-2" - > - -
-
{model.label}
- {model.contextWindow && ( -
- Context: {model.contextWindow} -
- )} -
-
- ))} -
- )} -
-
+ + + + +
+ {field.value ? `Using: "${field.value}"` : "Type your model name"} +
+
+ {availableModels.length > 0 && ( + + {availableModels + .filter( + (model) => + !field.value || + model.value.toLowerCase().includes(field.value.toLowerCase()) || + model.label.toLowerCase().includes(field.value.toLowerCase()) + ) + .slice(0, 50) + .map((model) => ( + { + field.onChange(value); + setModelComboboxOpen(false); + }} + className="py-2" + > + +
+
{model.label}
+ {model.contextWindow && ( +
+ Context: {model.contextWindow} +
+ )} +
+
+ ))} +
+ )} +
+
{selectedProvider?.example && ( diff --git a/surfsense_web/components/tool-ui/linear/create-linear-issue.tsx b/surfsense_web/components/tool-ui/linear/create-linear-issue.tsx index 5867863cc..b6eea7a28 100644 --- a/surfsense_web/components/tool-ui/linear/create-linear-issue.tsx +++ b/surfsense_web/components/tool-ui/linear/create-linear-issue.tsx @@ -215,9 +215,9 @@ function ApprovalCard({ onValueChange={(v) => { setSelectedWorkspaceId(v); setSelectedTeamId(""); - setSelectedStateId("__none__"); - setSelectedAssigneeId("__none__"); - setSelectedPriority("0"); + setSelectedStateId("__none__"); + setSelectedAssigneeId("__none__"); + setSelectedPriority("0"); setSelectedLabelIds([]); }} > @@ -243,13 +243,13 @@ function ApprovalCard({ setEditedArgs({ ...editedArgs, title: e.target.value })} - placeholder="Issue title" - /> - + setEditedArgs({ ...editedArgs, title: e.target.value })} + placeholder="Issue title" + /> + -
- -