diff --git a/web/.type-coverage-baseline.yaml b/web/.type-coverage-baseline.yaml index ef7a9aecf6..0ab7012c94 100644 --- a/web/.type-coverage-baseline.yaml +++ b/web/.type-coverage-baseline.yaml @@ -76,7 +76,6 @@ packages: src/lib/headers: 100 src/lib/hierarchy: 100 src/lib/hooks: 95.7 - src/lib/indexing: 99.4 src/lib/languageModels: 98.8 src/lib/multiModel: 100 src/lib/notifications: 99.3 @@ -86,6 +85,7 @@ packages: src/lib/projects: 99.7 src/lib/search: 99.1 src/lib/searchFilters: 95.3 + src/lib/searchSettings: 99.4 src/lib/settings: 96.6 src/lib/sidebar: 100 src/lib/skills: 97.4 diff --git a/web/src/lib/searchSettings/constants.ts b/web/src/lib/searchSettings/constants.ts new file mode 100644 index 0000000000..adb5a01d5b --- /dev/null +++ b/web/src/lib/searchSettings/constants.ts @@ -0,0 +1,251 @@ +import { SvgHardDrive } from "@opal/icons"; +import { + SvgAzure, + SvgCohere, + SvgGoogle, + SvgLitellm, + SvgMicrosoft, + SvgNomic, + SvgOpenai, + SvgVoyage, +} from "@opal/logos"; +import { + EmbeddingProvider, + EmbeddingProviderName, +} from "@/lib/searchSettings/types"; +import { DOCS_ADMINS_PATH } from "@/lib/constants"; + +// ═══════════════════════════════════════════════════════════════════════════ +// Embedding +// ═══════════════════════════════════════════════════════════════════════════ + +export const CLOUD_BASED_PROVIDERS: EmbeddingProvider[] = [ + { + providerName: EmbeddingProviderName.COHERE, + displayName: "Cohere", + icon: SvgCohere, + docsLink: `${DOCS_ADMINS_PATH}/advanced_configs/search_configs`, + apiLink: "https://dashboard.cohere.ai/api-keys", + costslink: "https://cohere.com/pricing", + embeddingModels: [ + { + modelName: "embed-english-v3.0", + modelDim: 1024, + normalize: false, + queryPrefix: "", + passagePrefix: "", + descriptionKey: "modelDescriptions.cohereEmbedEnglishV3", + }, + { + modelName: "embed-english-light-v3.0", + modelDim: 384, + normalize: false, + queryPrefix: "", + passagePrefix: "", + descriptionKey: "modelDescriptions.cohereEmbedEnglishLightV3", + }, + { + modelName: "embed-v4.0", + modelDim: 1536, + normalize: false, + queryPrefix: "", + passagePrefix: "", + descriptionKey: "modelDescriptions.cohereEmbedV4", + }, + ], + }, + { + providerName: EmbeddingProviderName.OPENAI, + displayName: "OpenAI", + icon: SvgOpenai, + docsLink: `${DOCS_ADMINS_PATH}/advanced_configs/search_configs`, + apiLink: "https://platform.openai.com/api-keys", + costslink: "https://openai.com/pricing", + embeddingModels: [ + { + modelName: "text-embedding-3-large", + modelDim: 3072, + normalize: false, + queryPrefix: "", + passagePrefix: "", + descriptionKey: "modelDescriptions.openaiTextEmbedding3Large", + }, + { + modelName: "text-embedding-3-small", + modelDim: 1536, + normalize: false, + queryPrefix: "", + passagePrefix: "", + descriptionKey: "modelDescriptions.openaiTextEmbedding3Small", + }, + ], + }, + { + providerName: EmbeddingProviderName.GOOGLE, + displayName: "Google", + icon: SvgGoogle, + docsLink: `${DOCS_ADMINS_PATH}/advanced_configs/search_configs`, + apiLink: "https://console.cloud.google.com/apis/credentials", + costslink: "https://cloud.google.com/vertex-ai/pricing", + embeddingModels: [ + { + modelName: "gemini-embedding-001", + modelDim: 3072, + normalize: false, + queryPrefix: "", + passagePrefix: "", + descriptionKey: "modelDescriptions.googleGeminiEmbedding001", + }, + { + modelName: "text-embedding-005", + modelDim: 768, + normalize: false, + queryPrefix: "", + passagePrefix: "", + descriptionKey: "modelDescriptions.googleTextEmbedding005", + }, + { + modelName: "gemini-embedding-2", + modelDim: 3072, + normalize: false, + queryPrefix: "", + passagePrefix: "", + descriptionKey: "modelDescriptions.googleGeminiEmbedding2", + }, + { + modelName: "gemini-embedding-2-preview", + modelDim: 3072, + normalize: false, + queryPrefix: "", + passagePrefix: "", + descriptionKey: "modelDescriptions.googleGeminiEmbedding2Preview", + }, + ], + }, + { + providerName: EmbeddingProviderName.VOYAGE, + displayName: "Voyage", + icon: SvgVoyage, + docsLink: `${DOCS_ADMINS_PATH}/advanced_configs/search_configs`, + apiLink: "https://www.voyageai.com/dashboard", + costslink: "https://www.voyageai.com/pricing", + deprecated: true, + embeddingModels: [ + { + modelName: "voyage-large-2-instruct", + modelDim: 1024, + normalize: false, + queryPrefix: "", + passagePrefix: "", + descriptionKey: "modelDescriptions.voyageLarge2Instruct", + }, + { + modelName: "voyage-light-2-instruct", + modelDim: 1024, + normalize: false, + queryPrefix: "", + passagePrefix: "", + descriptionKey: "modelDescriptions.voyageLight2Instruct", + }, + ], + }, + { + providerName: EmbeddingProviderName.LITELLM, + displayName: "LiteLLM", + icon: SvgLitellm, + apiLink: "https://docs.litellm.ai/docs/proxy/quick_start", + embeddingModels: [], + }, + { + providerName: EmbeddingProviderName.AZURE, + displayName: "Azure", + icon: SvgAzure, + apiLink: + "https://docs.microsoft.com/en-us/azure/ai-services/openai/how-to/create-resource", + costslink: + "https://azure.microsoft.com/en-us/pricing/details/cognitive-services/openai/", + embeddingModels: [], + }, +]; + +export const SELF_HOSTED_PROVIDERS: EmbeddingProvider[] = [ + { + providerName: EmbeddingProviderName.NOMIC, + displayName: "Nomic", + icon: SvgNomic, + docsLink: "https://huggingface.co/nomic-ai", + embeddingModels: [ + { + modelName: "nomic-ai/nomic-embed-text-v1", + modelDim: 768, + normalize: true, + queryPrefix: "search_query: ", + passagePrefix: "search_document: ", + descriptionKey: "modelDescriptions.nomicEmbedTextV1", + }, + ], + }, + { + providerName: EmbeddingProviderName.MICROSOFT, + displayName: "Microsoft", + icon: SvgMicrosoft, + docsLink: "https://huggingface.co/intfloat", + embeddingModels: [ + { + modelName: "intfloat/e5-base-v2", + modelDim: 768, + normalize: true, + queryPrefix: "query: ", + passagePrefix: "passage: ", + descriptionKey: "modelDescriptions.e5BaseV2", + }, + { + modelName: "intfloat/e5-small-v2", + modelDim: 384, + normalize: true, + queryPrefix: "query: ", + passagePrefix: "passage: ", + descriptionKey: "modelDescriptions.e5SmallV2", + }, + { + modelName: "intfloat/multilingual-e5-base", + modelDim: 768, + normalize: true, + queryPrefix: "query: ", + passagePrefix: "passage: ", + descriptionKey: "modelDescriptions.multilingualE5Base", + }, + { + modelName: "intfloat/multilingual-e5-small", + modelDim: 384, + normalize: true, + queryPrefix: "query: ", + passagePrefix: "passage: ", + descriptionKey: "modelDescriptions.multilingualE5Small", + }, + ], + }, +]; + +/** + * Synthetic provider used by the "Add Custom Model" flow. Not a real provider — + * its `providerName` never reaches the backend (custom self-hosted models are + * persisted with `provider_type=null` like other self-hosted models). Exists so + * the modal can be dispatched through `ProviderCredentialsModal` like every + * other provider. + */ +export const CUSTOM_PROVIDER: EmbeddingProvider = { + providerName: EmbeddingProviderName.CUSTOM, + displayName: "Custom Model", + icon: SvgHardDrive, + embeddingModels: [], +}; + +// ═══════════════════════════════════════════════════════════════════════════ +// Image processing +// ═══════════════════════════════════════════════════════════════════════════ + +export const MAX_IMAGE_SIZE_OPTIONS = ["5", "10", "20", "50", "100"]; + +/** Mirrors `DEFAULT_IMAGE_ANALYSIS_MAX_SIZE_MB` on the backend. */ +export const DEFAULT_IMAGE_ANALYSIS_MAX_SIZE_MB = 20; diff --git a/web/src/hooks/useSearchSettings.test.ts b/web/src/lib/searchSettings/hooks.test.ts similarity index 82% rename from web/src/hooks/useSearchSettings.test.ts rename to web/src/lib/searchSettings/hooks.test.ts index e1f4f74198..ecd6005fdf 100644 --- a/web/src/hooks/useSearchSettings.test.ts +++ b/web/src/lib/searchSettings/hooks.test.ts @@ -1,5 +1,5 @@ -import { secondaryRefreshInterval } from "@/lib/indexing/hooks"; -import type { EmbeddingModelResponse } from "@/lib/indexing/types"; +import { secondaryRefreshInterval } from "@/lib/searchSettings/hooks"; +import type { EmbeddingModelResponse } from "@/lib/searchSettings/types"; const embeddingModelResponse: EmbeddingModelResponse = { model_name: "text-embedding-3-small", diff --git a/web/src/lib/indexing/hooks.ts b/web/src/lib/searchSettings/hooks.ts similarity index 91% rename from web/src/lib/indexing/hooks.ts rename to web/src/lib/searchSettings/hooks.ts index 529203af8d..fadedd3cde 100644 --- a/web/src/lib/indexing/hooks.ts +++ b/web/src/lib/searchSettings/hooks.ts @@ -18,8 +18,9 @@ import { LLMContextualCost, ReindexErrorRow, ReindexProgress, + ImageProcessingSettings, SavedSearchSettings, -} from "@/lib/indexing/types"; +} from "@/lib/searchSettings/types"; /** * Determines the SWR `refreshInterval` for the secondary (in-progress) @@ -129,3 +130,14 @@ export function useConfiguredEmbeddingProviders() { errorHandlingFetcher ); } + +/** + * The tenant's image processing settings. `data` is `null` when the feature + * is off and `undefined` while loading. + */ +export function useImageProcessingSettings() { + return useSWR( + SWR_KEYS.imageProcessingSettings, + errorHandlingFetcher + ); +} diff --git a/web/src/lib/indexing/index.ts b/web/src/lib/searchSettings/index.ts similarity index 50% rename from web/src/lib/indexing/index.ts rename to web/src/lib/searchSettings/index.ts index 4e09c896c5..3e8934531d 100644 --- a/web/src/lib/indexing/index.ts +++ b/web/src/lib/searchSettings/index.ts @@ -1,247 +1,14 @@ -import { SvgHardDrive } from "@opal/icons"; import { - SvgAzure, - SvgCohere, - SvgGoogle, - SvgLitellm, - SvgMicrosoft, - SvgNomic, - SvgOpenai, - SvgVoyage, -} from "@opal/logos"; + CLOUD_BASED_PROVIDERS, + CUSTOM_PROVIDER, + SELF_HOSTED_PROVIDERS, +} from "@/lib/searchSettings/constants"; import { EmbeddingModel, EmbeddingProvider, EmbeddingProviderName, IndexSettingsTranslator, -} from "@/lib/indexing/types"; -import { DOCS_ADMINS_PATH } from "@/lib/constants"; - -// ═══════════════════════════════════════════════════════════════════════════ -// Embedding -// ═══════════════════════════════════════════════════════════════════════════ - -export const CLOUD_BASED_PROVIDERS: EmbeddingProvider[] = [ - { - providerName: EmbeddingProviderName.COHERE, - displayName: "Cohere", - icon: SvgCohere, - docsLink: `${DOCS_ADMINS_PATH}/advanced_configs/search_configs`, - apiLink: "https://dashboard.cohere.ai/api-keys", - costslink: "https://cohere.com/pricing", - embeddingModels: [ - { - modelName: "embed-english-v3.0", - modelDim: 1024, - normalize: false, - queryPrefix: "", - passagePrefix: "", - descriptionKey: "modelDescriptions.cohereEmbedEnglishV3", - }, - { - modelName: "embed-english-light-v3.0", - modelDim: 384, - normalize: false, - queryPrefix: "", - passagePrefix: "", - descriptionKey: "modelDescriptions.cohereEmbedEnglishLightV3", - }, - { - modelName: "embed-v4.0", - modelDim: 1536, - normalize: false, - queryPrefix: "", - passagePrefix: "", - descriptionKey: "modelDescriptions.cohereEmbedV4", - }, - ], - }, - { - providerName: EmbeddingProviderName.OPENAI, - displayName: "OpenAI", - icon: SvgOpenai, - docsLink: `${DOCS_ADMINS_PATH}/advanced_configs/search_configs`, - apiLink: "https://platform.openai.com/api-keys", - costslink: "https://openai.com/pricing", - embeddingModels: [ - { - modelName: "text-embedding-3-large", - modelDim: 3072, - normalize: false, - queryPrefix: "", - passagePrefix: "", - descriptionKey: "modelDescriptions.openaiTextEmbedding3Large", - }, - { - modelName: "text-embedding-3-small", - modelDim: 1536, - normalize: false, - queryPrefix: "", - passagePrefix: "", - descriptionKey: "modelDescriptions.openaiTextEmbedding3Small", - }, - ], - }, - { - providerName: EmbeddingProviderName.GOOGLE, - displayName: "Google", - icon: SvgGoogle, - docsLink: `${DOCS_ADMINS_PATH}/advanced_configs/search_configs`, - apiLink: "https://console.cloud.google.com/apis/credentials", - costslink: "https://cloud.google.com/vertex-ai/pricing", - embeddingModels: [ - { - modelName: "gemini-embedding-001", - modelDim: 3072, - normalize: false, - queryPrefix: "", - passagePrefix: "", - descriptionKey: "modelDescriptions.googleGeminiEmbedding001", - }, - { - modelName: "text-embedding-005", - modelDim: 768, - normalize: false, - queryPrefix: "", - passagePrefix: "", - descriptionKey: "modelDescriptions.googleTextEmbedding005", - }, - { - modelName: "gemini-embedding-2", - modelDim: 3072, - normalize: false, - queryPrefix: "", - passagePrefix: "", - descriptionKey: "modelDescriptions.googleGeminiEmbedding2", - }, - { - modelName: "gemini-embedding-2-preview", - modelDim: 3072, - normalize: false, - queryPrefix: "", - passagePrefix: "", - descriptionKey: "modelDescriptions.googleGeminiEmbedding2Preview", - }, - ], - }, - { - providerName: EmbeddingProviderName.VOYAGE, - displayName: "Voyage", - icon: SvgVoyage, - docsLink: `${DOCS_ADMINS_PATH}/advanced_configs/search_configs`, - apiLink: "https://www.voyageai.com/dashboard", - costslink: "https://www.voyageai.com/pricing", - deprecated: true, - embeddingModels: [ - { - modelName: "voyage-large-2-instruct", - modelDim: 1024, - normalize: false, - queryPrefix: "", - passagePrefix: "", - descriptionKey: "modelDescriptions.voyageLarge2Instruct", - }, - { - modelName: "voyage-light-2-instruct", - modelDim: 1024, - normalize: false, - queryPrefix: "", - passagePrefix: "", - descriptionKey: "modelDescriptions.voyageLight2Instruct", - }, - ], - }, - { - providerName: EmbeddingProviderName.LITELLM, - displayName: "LiteLLM", - icon: SvgLitellm, - apiLink: "https://docs.litellm.ai/docs/proxy/quick_start", - embeddingModels: [], - }, - { - providerName: EmbeddingProviderName.AZURE, - displayName: "Azure", - icon: SvgAzure, - apiLink: - "https://docs.microsoft.com/en-us/azure/ai-services/openai/how-to/create-resource", - costslink: - "https://azure.microsoft.com/en-us/pricing/details/cognitive-services/openai/", - embeddingModels: [], - }, -]; - -export const SELF_HOSTED_PROVIDERS: EmbeddingProvider[] = [ - { - providerName: EmbeddingProviderName.NOMIC, - displayName: "Nomic", - icon: SvgNomic, - docsLink: "https://huggingface.co/nomic-ai", - embeddingModels: [ - { - modelName: "nomic-ai/nomic-embed-text-v1", - modelDim: 768, - normalize: true, - queryPrefix: "search_query: ", - passagePrefix: "search_document: ", - descriptionKey: "modelDescriptions.nomicEmbedTextV1", - }, - ], - }, - { - providerName: EmbeddingProviderName.MICROSOFT, - displayName: "Microsoft", - icon: SvgMicrosoft, - docsLink: "https://huggingface.co/intfloat", - embeddingModels: [ - { - modelName: "intfloat/e5-base-v2", - modelDim: 768, - normalize: true, - queryPrefix: "query: ", - passagePrefix: "passage: ", - descriptionKey: "modelDescriptions.e5BaseV2", - }, - { - modelName: "intfloat/e5-small-v2", - modelDim: 384, - normalize: true, - queryPrefix: "query: ", - passagePrefix: "passage: ", - descriptionKey: "modelDescriptions.e5SmallV2", - }, - { - modelName: "intfloat/multilingual-e5-base", - modelDim: 768, - normalize: true, - queryPrefix: "query: ", - passagePrefix: "passage: ", - descriptionKey: "modelDescriptions.multilingualE5Base", - }, - { - modelName: "intfloat/multilingual-e5-small", - modelDim: 384, - normalize: true, - queryPrefix: "query: ", - passagePrefix: "passage: ", - descriptionKey: "modelDescriptions.multilingualE5Small", - }, - ], - }, -]; - -/** - * Synthetic provider used by the "Add Custom Model" flow. Not a real provider — - * its `providerName` never reaches the backend (custom self-hosted models are - * persisted with `provider_type=null` like other self-hosted models). Exists so - * the modal can be dispatched through `ProviderCredentialsModal` like every - * other provider. - */ -export const CUSTOM_PROVIDER: EmbeddingProvider = { - providerName: EmbeddingProviderName.CUSTOM, - displayName: "Custom Model", - icon: SvgHardDrive, - embeddingModels: [], -}; +} from "@/lib/searchSettings/types"; /** * Total lookup of an {@link EmbeddingProvider} by its `providerName`. @@ -412,9 +179,3 @@ export function resolveProviderName( } return EmbeddingProviderName.CUSTOM; } - -// ═══════════════════════════════════════════════════════════════════════════ -// Image processing -// ═══════════════════════════════════════════════════════════════════════════ - -export const MAX_IMAGE_SIZE_OPTIONS = ["5", "10", "20", "50", "100"]; diff --git a/web/src/lib/indexing/modelSelection.test.ts b/web/src/lib/searchSettings/modelSelection.test.ts similarity index 98% rename from web/src/lib/indexing/modelSelection.test.ts rename to web/src/lib/searchSettings/modelSelection.test.ts index e3a13eb935..5b7d509a2f 100644 --- a/web/src/lib/indexing/modelSelection.test.ts +++ b/web/src/lib/searchSettings/modelSelection.test.ts @@ -2,11 +2,11 @@ import { isSameModelSelection, resolveModelForApply, savedModelSelection, -} from "@/lib/indexing/utils"; +} from "@/lib/searchSettings/utils"; import { EmbeddingModelSpec, EmbeddingProviderName, -} from "@/lib/indexing/types"; +} from "@/lib/searchSettings/types"; /** A deployment the static registry has never heard of, which is the whole point. */ function deployment(modelName: string): EmbeddingModelSpec { diff --git a/web/src/lib/indexing/svc.ts b/web/src/lib/searchSettings/svc.ts similarity index 74% rename from web/src/lib/indexing/svc.ts rename to web/src/lib/searchSettings/svc.ts index 8d1e05032e..863eef4e3e 100644 --- a/web/src/lib/indexing/svc.ts +++ b/web/src/lib/searchSettings/svc.ts @@ -4,11 +4,12 @@ import { SWR_KEYS } from "@/lib/swr-keys"; import { EmbeddingModelSpec, EmbeddingProviderName, + ImageProcessingSettings, ReindexErrorRow, SavedSearchSettings, SwitchoverType, -} from "@/lib/indexing/types"; -import { isCloudBased } from "@/lib/indexing"; +} from "@/lib/searchSettings/types"; +import { isCloudBased } from "@/lib/searchSettings"; interface TestEmbeddingArgs { provider_type: string; @@ -238,3 +239,71 @@ export async function updateInferenceSettings( body: JSON.stringify(settings), }); } + +// ═══════════════════════════════════════════════════════════════════════════ +// Image processing +// ═══════════════════════════════════════════════════════════════════════════ + +interface EnableImageProcessingArgs { + modelConfigurationId: number; + maxSizeMb: number; +} + +/** + * A failed image processing request. `detail` is the server's reason when + * the body carried one, else null; the caller chooses a translated fallback. + */ +export class ImageProcessingRequestError extends Error { + constructor( + readonly status: number, + readonly detail: string | null + ) { + super(detail ?? `Image processing request failed with status ${status}`); + this.name = "ImageProcessingRequestError"; + } +} + +async function throwOnError(response: Response): Promise { + if (response.ok) return; + let detail: string | null = null; + try { + const body: unknown = await response.json(); + if ( + typeof body === "object" && + body !== null && + "detail" in body && + typeof body.detail === "string" + ) { + detail = body.detail; + } + } catch (error) { + // A non-JSON body (a proxy page, a truncated response) is worth a trace. + console.error("Image processing error response was not JSON:", error); + } + throw new ImageProcessingRequestError(response.status, detail); +} + +/** Turns image processing on with this model, or repoints it. */ +export async function enableImageProcessing({ + modelConfigurationId, + maxSizeMb, +}: EnableImageProcessingArgs): Promise { + const response = await fetch(SWR_KEYS.imageProcessingSettings, { + method: "PUT", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + model_configuration_id: modelConfigurationId, + max_size_mb: maxSizeMb, + }), + }); + await throwOnError(response); + return (await response.json()) as ImageProcessingSettings; +} + +/** Turns image processing off. */ +export async function disableImageProcessing(): Promise { + const response = await fetch(SWR_KEYS.imageProcessingSettings, { + method: "DELETE", + }); + await throwOnError(response); +} diff --git a/web/src/lib/indexing/types.ts b/web/src/lib/searchSettings/types.ts similarity index 93% rename from web/src/lib/indexing/types.ts rename to web/src/lib/searchSettings/types.ts index 7c3d26a081..1d3566f713 100644 --- a/web/src/lib/indexing/types.ts +++ b/web/src/lib/searchSettings/types.ts @@ -212,3 +212,16 @@ export interface ReindexErrorRow { error_msg: string | null; paused: boolean; } + +// --------------------------------------------------------------------------- +// Image processing +// --------------------------------------------------------------------------- + +/** + * The tenant's image processing (captioning) configuration. `null` from the + * API means the feature is off; a value means it is on with that model. + */ +export interface ImageProcessingSettings { + model_configuration_id: number; + max_size_mb: number; +} diff --git a/web/src/lib/indexing/utils.ts b/web/src/lib/searchSettings/utils.ts similarity index 94% rename from web/src/lib/indexing/utils.ts rename to web/src/lib/searchSettings/utils.ts index 8aa4bef8cd..447c22acf9 100644 --- a/web/src/lib/indexing/utils.ts +++ b/web/src/lib/searchSettings/utils.ts @@ -1,10 +1,10 @@ -import { findRegistryModel, resolveProviderName } from "@/lib/indexing"; +import { findRegistryModel, resolveProviderName } from "@/lib/searchSettings"; import type { EmbeddingModelSelection, EmbeddingModelSpec, EmbeddingProviderName, ResolvedEmbeddingModelForApply, -} from "@/lib/indexing/types"; +} from "@/lib/searchSettings/types"; export function savedModelSelection( currentModel: EmbeddingModelSpec | null, diff --git a/web/src/lib/swr-keys.ts b/web/src/lib/swr-keys.ts index 4628e66145..04e2b20fe7 100644 --- a/web/src/lib/swr-keys.ts +++ b/web/src/lib/swr-keys.ts @@ -83,6 +83,7 @@ export const SWR_KEYS = { // ── Search Settings ─────────────────────────────────────────────────────── currentSearchSettings: "/api/search-settings/get-current-search-settings", + imageProcessingSettings: "/api/admin/image-processing", secondarySearchSettings: "/api/search-settings/get-secondary-search-settings", reindexProgress: "/api/search-settings/reindex-progress", reindexErrors: "/api/search-settings/reindex-errors", diff --git a/web/src/views/admin/IndexSettingsPage/ReindexErrorsModal.tsx b/web/src/views/admin/IndexSettingsPage/ReindexErrorsModal.tsx index ee5d81fbb2..f9101f441e 100644 --- a/web/src/views/admin/IndexSettingsPage/ReindexErrorsModal.tsx +++ b/web/src/views/admin/IndexSettingsPage/ReindexErrorsModal.tsx @@ -10,10 +10,10 @@ import { createTableColumns, } from "@opal/components"; import { SvgAlertCircle, SvgPauseCircle, SvgPlayCircle } from "@opal/icons"; -import { useReindexErrors } from "@/lib/indexing/hooks"; -import { resumePausedPort } from "@/lib/indexing/svc"; +import { useReindexErrors } from "@/lib/searchSettings/hooks"; +import { resumePausedPort } from "@/lib/searchSettings/svc"; import { SWR_KEYS } from "@/lib/swr-keys"; -import type { ReindexErrorRow } from "@/lib/indexing/types"; +import type { ReindexErrorRow } from "@/lib/searchSettings/types"; function ResumeButton({ row }: { row: ReindexErrorRow }) { const t = useTranslations("admin.indexSettings"); diff --git a/web/src/views/admin/IndexSettingsPage/ReindexProgressBanner.tsx b/web/src/views/admin/IndexSettingsPage/ReindexProgressBanner.tsx index 010c41109c..a2e4ae20f8 100644 --- a/web/src/views/admin/IndexSettingsPage/ReindexProgressBanner.tsx +++ b/web/src/views/admin/IndexSettingsPage/ReindexProgressBanner.tsx @@ -14,7 +14,7 @@ import { SvgPauseCircle, } from "@opal/icons"; import ReindexErrorsModal from "@/views/admin/IndexSettingsPage/ReindexErrorsModal"; -import { useReindexProgress } from "@/lib/indexing/hooks"; +import { useReindexProgress } from "@/lib/searchSettings/hooks"; interface ReindexProgressBannerProps { secondaryModelName?: string; diff --git a/web/src/views/admin/IndexSettingsPage/index.tsx b/web/src/views/admin/IndexSettingsPage/index.tsx index 8d49b28cb5..c5662f1c6c 100644 --- a/web/src/views/admin/IndexSettingsPage/index.tsx +++ b/web/src/views/admin/IndexSettingsPage/index.tsx @@ -62,30 +62,32 @@ import { type EmbeddingModelSelection, type EmbeddingModelState, type EmbeddingProvider, -} from "@/lib/indexing/types"; +} from "@/lib/searchSettings/types"; import { CLOUD_BASED_PROVIDERS, CUSTOM_PROVIDER, + MAX_IMAGE_SIZE_OPTIONS, SELF_HOSTED_PROVIDERS, +} from "@/lib/searchSettings/constants"; +import { embeddingModelDescription, findProvider, findRegistryModel, isCloudBased, - MAX_IMAGE_SIZE_OPTIONS, resolveProviderName, -} from "@/lib/indexing"; +} from "@/lib/searchSettings"; import { isSameModelSelection, resolveModelForApply, savedModelSelection, -} from "@/lib/indexing/utils"; +} from "@/lib/searchSettings/utils"; import { saveAdminSettings, cancelNewEmbedding, disconnectEmbeddingProvider, setNewSearchSettings, updateInferenceSettings, -} from "@/lib/indexing/svc"; +} from "@/lib/searchSettings/svc"; import { useCreateModal } from "@opal/components"; import { ContentAction } from "@opal/layouts"; import { ConfirmationModalLayout } from "@opal/layouts"; @@ -98,7 +100,7 @@ import { useCurrentSearchSettings, useReindexProgress, useSecondarySearchSettings, -} from "@/lib/indexing/hooks"; +} from "@/lib/searchSettings/hooks"; import { useLlmDefaults } from "@/lib/languageModels/hooks"; import useFilter from "@/hooks/useFilter"; import ModelSelector from "@/sections/model-selector/ModelSelector"; diff --git a/web/src/views/admin/IndexSettingsPage/modals.tsx b/web/src/views/admin/IndexSettingsPage/modals.tsx index 60e0804e7c..464bca5122 100644 --- a/web/src/views/admin/IndexSettingsPage/modals.tsx +++ b/web/src/views/admin/IndexSettingsPage/modals.tsx @@ -15,8 +15,11 @@ import { type ConfiguredEmbeddingProvider, type EmbeddingModel, type EmbeddingProvider, -} from "@/lib/indexing/types"; -import { connectEmbeddingProvider, testEmbedding } from "@/lib/indexing/svc"; +} from "@/lib/searchSettings/types"; +import { + connectEmbeddingProvider, + testEmbedding, +} from "@/lib/searchSettings/svc"; import { ApiKeyField, ApiUrlField, diff --git a/web/src/views/admin/IndexSettingsPage/shared.tsx b/web/src/views/admin/IndexSettingsPage/shared.tsx index a97cbd6e61..1f0a8b1d2a 100644 --- a/web/src/views/admin/IndexSettingsPage/shared.tsx +++ b/web/src/views/admin/IndexSettingsPage/shared.tsx @@ -11,7 +11,7 @@ import { InputHorizontal, InputVertical } from "@opal/layouts"; import type { EmbeddingProvider, IndexSettingsTranslator, -} from "@/lib/indexing/types"; +} from "@/lib/searchSettings/types"; import SwitchField from "@/refresh-components/form/SwitchField"; import InputTypeInField from "@/refresh-components/form/InputTypeInField"; import PasswordInputTypeInField from "@/refresh-components/form/PasswordInputTypeInField";