mirror of
https://github.com/docmost/docmost.git
synced 2026-08-19 18:44:09 +08:00
feat(ai): pre-warm the vector namespace
This commit is contained in:
@@ -15,6 +15,14 @@ export interface IAiSearchResponse {
|
|||||||
}>;
|
}>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function hintVectorCache(): Promise<void> {
|
||||||
|
try {
|
||||||
|
await api.post("/ai/vector-cache-hint");
|
||||||
|
} catch {
|
||||||
|
// best-effort cache hint
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export async function aiAnswers(
|
export async function aiAnswers(
|
||||||
params: IPageSearchParams,
|
params: IPageSearchParams,
|
||||||
onChunk?: (chunk: { content?: string; sources?: any[] }) => void,
|
onChunk?: (chunk: { content?: string; sources?: any[] }) => void,
|
||||||
|
|||||||
@@ -13,11 +13,16 @@ import { SearchResultItem } from "./search-result-item.tsx";
|
|||||||
import { AiSearchResult } from "../../../ee/ai/components/ai-search-result.tsx";
|
import { AiSearchResult } from "../../../ee/ai/components/ai-search-result.tsx";
|
||||||
import { useHasFeature } from "@/ee/hooks/use-feature";
|
import { useHasFeature } from "@/ee/hooks/use-feature";
|
||||||
import { Feature } from "@/ee/features";
|
import { Feature } from "@/ee/features";
|
||||||
|
import { useAtomValue } from "jotai";
|
||||||
|
import { workspaceAtom } from "@/features/user/atoms/current-user-atom.ts";
|
||||||
|
import { hintVectorCache } from "@/ee/ai/services/ai-search-service.ts";
|
||||||
|
import { getAiVectorDriver } from "@/lib/config.ts";
|
||||||
|
|
||||||
interface SearchSpotlightProps {
|
interface SearchSpotlightProps {
|
||||||
spaceId?: string;
|
spaceId?: string;
|
||||||
}
|
}
|
||||||
export function SearchSpotlight({ spaceId }: SearchSpotlightProps) {
|
export function SearchSpotlight({ spaceId }: SearchSpotlightProps) {
|
||||||
|
const workspace = useAtomValue(workspaceAtom);
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const hasAiFeature = useHasFeature(Feature.AI);
|
const hasAiFeature = useHasFeature(Feature.AI);
|
||||||
const hasAttachmentIndexing = useHasFeature(Feature.ATTACHMENT_INDEXING);
|
const hasAttachmentIndexing = useHasFeature(Feature.ATTACHMENT_INDEXING);
|
||||||
@@ -96,6 +101,15 @@ export function SearchSpotlight({ spaceId }: SearchSpotlightProps) {
|
|||||||
/>
|
/>
|
||||||
));
|
));
|
||||||
|
|
||||||
|
const handleSpotlightOpen = () => {
|
||||||
|
if (
|
||||||
|
workspace?.settings?.ai?.search === true &&
|
||||||
|
getAiVectorDriver() === "turbopuffer"
|
||||||
|
) {
|
||||||
|
hintVectorCache();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const handleFiltersChange = (newFilters: any) => {
|
const handleFiltersChange = (newFilters: any) => {
|
||||||
setFilters(newFilters);
|
setFilters(newFilters);
|
||||||
};
|
};
|
||||||
@@ -115,6 +129,7 @@ export function SearchSpotlight({ spaceId }: SearchSpotlightProps) {
|
|||||||
<Spotlight.Root
|
<Spotlight.Root
|
||||||
size="xl"
|
size="xl"
|
||||||
maxHeight={600}
|
maxHeight={600}
|
||||||
|
onSpotlightOpen={handleSpotlightOpen}
|
||||||
store={searchSpotlightStore}
|
store={searchSpotlightStore}
|
||||||
query={query}
|
query={query}
|
||||||
onQueryChange={setQuery}
|
onQueryChange={setQuery}
|
||||||
|
|||||||
@@ -43,6 +43,10 @@ export function isCloud(): boolean {
|
|||||||
return castToBoolean(getConfigValue("CLOUD"));
|
return castToBoolean(getConfigValue("CLOUD"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getAiVectorDriver(): string {
|
||||||
|
return getConfigValue("AI_VECTOR_DRIVER");
|
||||||
|
}
|
||||||
|
|
||||||
export function getAvatarUrl(
|
export function getAvatarUrl(
|
||||||
avatarUrl: string,
|
avatarUrl: string,
|
||||||
type: AvatarIconType = AvatarIconType.AVATAR,
|
type: AvatarIconType = AvatarIconType.AVATAR,
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ export enum EventName {
|
|||||||
WORKSPACE_CREATED = 'workspace.created',
|
WORKSPACE_CREATED = 'workspace.created',
|
||||||
WORKSPACE_UPDATED = 'workspace.updated',
|
WORKSPACE_UPDATED = 'workspace.updated',
|
||||||
WORKSPACE_DELETED = 'workspace.deleted',
|
WORKSPACE_DELETED = 'workspace.deleted',
|
||||||
USER_SESSION_STARTED = 'user.session.started',
|
|
||||||
|
|
||||||
BASE_CREATED = 'base.created',
|
BASE_CREATED = 'base.created',
|
||||||
BASE_UPDATED = 'base.updated',
|
BASE_UPDATED = 'base.updated',
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import {
|
|||||||
Post,
|
Post,
|
||||||
UseGuards,
|
UseGuards,
|
||||||
} from '@nestjs/common';
|
} from '@nestjs/common';
|
||||||
import { EventEmitter2 } from '@nestjs/event-emitter';
|
|
||||||
import { UserService } from './user.service';
|
import { UserService } from './user.service';
|
||||||
import { UpdateUserDto } from './dto/update-user.dto';
|
import { UpdateUserDto } from './dto/update-user.dto';
|
||||||
import { AuthUser } from '../../common/decorators/auth-user.decorator';
|
import { AuthUser } from '../../common/decorators/auth-user.decorator';
|
||||||
@@ -14,7 +13,6 @@ import { JwtAuthGuard } from '../../common/guards/jwt-auth.guard';
|
|||||||
import { AuthWorkspace } from '../../common/decorators/auth-workspace.decorator';
|
import { AuthWorkspace } from '../../common/decorators/auth-workspace.decorator';
|
||||||
import { User, Workspace } from '@docmost/db/types/entity.types';
|
import { User, Workspace } from '@docmost/db/types/entity.types';
|
||||||
import { WorkspaceRepo } from '@docmost/db/repos/workspace/workspace.repo';
|
import { WorkspaceRepo } from '@docmost/db/repos/workspace/workspace.repo';
|
||||||
import { EventName } from '../../common/events/event.contants';
|
|
||||||
|
|
||||||
@UseGuards(JwtAuthGuard)
|
@UseGuards(JwtAuthGuard)
|
||||||
@Controller('users')
|
@Controller('users')
|
||||||
@@ -22,7 +20,6 @@ export class UserController {
|
|||||||
constructor(
|
constructor(
|
||||||
private readonly userService: UserService,
|
private readonly userService: UserService,
|
||||||
private readonly workspaceRepo: WorkspaceRepo,
|
private readonly workspaceRepo: WorkspaceRepo,
|
||||||
private readonly eventEmitter: EventEmitter2,
|
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
@HttpCode(HttpStatus.OK)
|
@HttpCode(HttpStatus.OK)
|
||||||
@@ -42,11 +39,6 @@ export class UserController {
|
|||||||
memberCount,
|
memberCount,
|
||||||
};
|
};
|
||||||
|
|
||||||
this.eventEmitter.emit(EventName.USER_SESSION_STARTED, {
|
|
||||||
userId: authUser.id,
|
|
||||||
workspaceId: workspace.id,
|
|
||||||
});
|
|
||||||
|
|
||||||
return { user: authUser, workspace: workspaceInfo };
|
return { user: authUser, workspace: workspaceInfo };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
Submodule apps/server/src/ee updated: 0d0ab522af...660418ac2c
@@ -49,6 +49,10 @@ export class StaticModule implements OnModuleInit {
|
|||||||
: undefined,
|
: undefined,
|
||||||
POSTHOG_HOST: this.environmentService.getPostHogHost(),
|
POSTHOG_HOST: this.environmentService.getPostHogHost(),
|
||||||
POSTHOG_KEY: this.environmentService.getPostHogKey(),
|
POSTHOG_KEY: this.environmentService.getPostHogKey(),
|
||||||
|
AI_VECTOR_DRIVER:
|
||||||
|
this.environmentService.getAiVectorDriver() === 'turbopuffer'
|
||||||
|
? 'turbopuffer'
|
||||||
|
: undefined,
|
||||||
};
|
};
|
||||||
|
|
||||||
const windowScriptContent = `<script>window.CONFIG=${JSON.stringify(configString)};</script>`;
|
const windowScriptContent = `<script>window.CONFIG=${JSON.stringify(configString)};</script>`;
|
||||||
|
|||||||
Reference in New Issue
Block a user