diff --git a/apps/client/src/features/search/components/ai-search-result.tsx b/apps/client/src/features/search/components/ai-search-result.tsx
index cf67fb0b..b1a3db00 100644
--- a/apps/client/src/features/search/components/ai-search-result.tsx
+++ b/apps/client/src/features/search/components/ai-search-result.tsx
@@ -4,6 +4,8 @@ import { IconSparkles, IconFileText } from "@tabler/icons-react";
import { Link } from "react-router-dom";
import { IAiSearchResponse } from "../services/ai-search-service";
import { buildPageUrl } from "@/features/page/page.utils";
+import { markdownToHtml } from "@docmost/editor-ext";
+import DOMPurify from "dompurify";
interface AiSearchResultProps {
result: IAiSearchResponse;
@@ -14,7 +16,7 @@ export function AiSearchResult({ result, isLoading }: AiSearchResultProps) {
// Deduplicate sources by pageId, keeping the one with highest similarity
const deduplicatedSources = useMemo(() => {
if (!result?.sources) return [];
-
+
const pageMap = new Map();
result.sources.forEach((source) => {
const existing = pageMap.get(source.pageId);
@@ -22,7 +24,7 @@ export function AiSearchResult({ result, isLoading }: AiSearchResultProps) {
pageMap.set(source.pageId, source);
}
});
-
+
return Array.from(pageMap.values());
}, [result?.sources]);
@@ -46,11 +48,17 @@ export function AiSearchResult({ result, isLoading }: AiSearchResultProps) {
- AI Answer
+
+ AI Answer
+
-
- {result.answer}
-
+
{deduplicatedSources.length > 0 && (
@@ -63,10 +71,10 @@ export function AiSearchResult({ result, isLoading }: AiSearchResultProps) {
key={source.pageId}
component={Link}
to={buildPageUrl(source.spaceSlug, source.slugId, source.title)}
- style={{
+ style={{
textDecoration: "none",
color: "inherit",
- display: "block"
+ display: "block",
}}
>
);
-}
\ No newline at end of file
+}
diff --git a/apps/client/src/features/search/components/search-spotlight.tsx b/apps/client/src/features/search/components/search-spotlight.tsx
index 077952d9..b1869af5 100644
--- a/apps/client/src/features/search/components/search-spotlight.tsx
+++ b/apps/client/src/features/search/components/search-spotlight.tsx
@@ -28,7 +28,6 @@ export function SearchSpotlight({ spaceId }: SearchSpotlightProps) {
contentType: "page",
});
const [isAiMode, setIsAiMode] = useState(false);
- const [triggerAiSearch, setTriggerAiSearch] = useState(false);
// Build unified search params
const searchParams = useMemo(() => {
@@ -49,10 +48,7 @@ export function SearchSpotlight({ spaceId }: SearchSpotlightProps) {
searchParams,
!isAiMode // Disable regular search when in AI mode
);
- const { data: aiSearchResult, isLoading: isAiLoading, refetch: refetchAiSearch } = useAiSearch(
- searchParams,
- isAiMode && triggerAiSearch
- );
+ const { data: aiSearchResult, isPending: isAiLoading, mutate: triggerAiSearchMutation } = useAiSearch();
// Determine result type for rendering
const isAttachmentSearch =
@@ -72,16 +68,12 @@ export function SearchSpotlight({ spaceId }: SearchSpotlightProps) {
};
const handleAskClick = () => {
- const newMode = !isAiMode;
- setIsAiMode(newMode);
- // Reset AI search state when toggling modes
- setTriggerAiSearch(false);
+ setIsAiMode(!isAiMode);
};
const handleAiSearchTrigger = () => {
if (query.trim() && isAiMode) {
- setTriggerAiSearch(true);
- refetchAiSearch();
+ triggerAiSearchMutation(searchParams);
}
};
diff --git a/apps/client/src/features/search/hooks/use-ai-search.ts b/apps/client/src/features/search/hooks/use-ai-search.ts
index 6c70b428..872e77cf 100644
--- a/apps/client/src/features/search/hooks/use-ai-search.ts
+++ b/apps/client/src/features/search/hooks/use-ai-search.ts
@@ -1,21 +1,11 @@
-import { useQuery, UseQueryResult } from "@tanstack/react-query";
+import { useMutation, UseMutationResult } from "@tanstack/react-query";
import { askAi, IAiSearchResponse } from "@/features/search/services/ai-search-service";
import { IPageSearchParams } from "@/features/search/types/search.types";
-import { useLicense } from "@/ee/hooks/use-license";
-export function useAiSearch(
- params: IPageSearchParams,
- enabled: boolean = false,
-): UseQueryResult {
- const { hasLicenseKey } = useLicense();
-
- return useQuery({
- queryKey: ["ai-search", params],
- queryFn: async () => {
+export function useAiSearch(): UseMutationResult {
+ return useMutation({
+ mutationFn: async (params: IPageSearchParams) => {
return await askAi(params);
},
- enabled: !!params.query && hasLicenseKey && enabled,
- staleTime: Infinity, // Don't refetch automatically
- gcTime: 0, // Don't cache results when component unmounts
});
}
\ No newline at end of file
diff --git a/apps/server/src/core/search/search.service.ts b/apps/server/src/core/search/search.service.ts
index 0f8dbb90..29508797 100644
--- a/apps/server/src/core/search/search.service.ts
+++ b/apps/server/src/core/search/search.service.ts
@@ -62,7 +62,7 @@ export class SearchService {
)
.where('deletedAt', 'is', null)
.orderBy('rank', 'desc')
- .limit(searchParams.limit | 20)
+ .limit(searchParams.limit | 25)
.offset(searchParams.offset || 0);
if (!searchParams.shareId) {