mirror of
https://github.com/onyx-dot-app/onyx.git
synced 2026-10-19 01:50:51 -05:00
refactor(web): lib/indexing/ becomes lib/searchSettings/ (#14982)
This commit is contained in:
1 parent
6dbc329bcd
commit
e5e8fa0da7
15 files changed
+379
-267
No files matched your search
@@ -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
|
||||
|
||||
@@ -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;
|
||||
@@ -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",
|
||||
@@ -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<ImageProcessingSettings | null>(
|
||||
SWR_KEYS.imageProcessingSettings,
|
||||
errorHandlingFetcher
|
||||
);
|
||||
}
|
||||
@@ -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"];
|
||||
+2
-2
@@ -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 {
|
||||
@@ -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<void> {
|
||||
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<ImageProcessingSettings> {
|
||||
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<void> {
|
||||
const response = await fetch(SWR_KEYS.imageProcessingSettings, {
|
||||
method: "DELETE",
|
||||
});
|
||||
await throwOnError(response);
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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,
|
||||
@@ -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",
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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";
|
||||
|
||||
Reference in new issue
Block a user