Merge branch 'master' of github.com:Mintplex-Labs/anything-llm
This commit is contained in:
commit
adef26a714
@ -1,3 +1,6 @@
|
|||||||
|
import { Info } from "@phosphor-icons/react";
|
||||||
|
import { Tooltip } from "react-tooltip";
|
||||||
|
|
||||||
const DEFAULT_MODELS = [
|
const DEFAULT_MODELS = [
|
||||||
{
|
{
|
||||||
id: "gemini-embedding-001",
|
id: "gemini-embedding-001",
|
||||||
@ -7,47 +10,93 @@ const DEFAULT_MODELS = [
|
|||||||
|
|
||||||
export default function GeminiOptions({ settings }) {
|
export default function GeminiOptions({ settings }) {
|
||||||
return (
|
return (
|
||||||
<div className="w-full flex flex-col gap-y-4">
|
<div className="w-full flex flex-col gap-y-6">
|
||||||
<div className="w-full flex items-center gap-[36px] mt-1.5">
|
<div className="w-full flex flex-col gap-y-4">
|
||||||
<div className="flex flex-col w-60">
|
<div className="w-full flex items-center gap-[36px] mt-1.5">
|
||||||
<label className="text-white text-sm font-semibold block mb-3">
|
<div className="flex flex-col w-60">
|
||||||
API Key
|
<label className="text-white text-sm font-semibold block mb-3">
|
||||||
|
API Key
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="password"
|
||||||
|
name="GeminiEmbeddingApiKey"
|
||||||
|
className="border-none bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||||
|
placeholder="Gemini API Key"
|
||||||
|
defaultValue={
|
||||||
|
settings?.GeminiEmbeddingApiKey ? "*".repeat(20) : ""
|
||||||
|
}
|
||||||
|
required={true}
|
||||||
|
autoComplete="off"
|
||||||
|
spellCheck={false}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="flex flex-col w-60">
|
||||||
|
<label className="text-white text-sm font-semibold block mb-3">
|
||||||
|
Model Preference
|
||||||
|
</label>
|
||||||
|
<select
|
||||||
|
name="EmbeddingModelPref"
|
||||||
|
required={true}
|
||||||
|
className="border-none bg-theme-settings-input-bg border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||||
|
>
|
||||||
|
<optgroup label="Available embedding models">
|
||||||
|
{DEFAULT_MODELS.map((model) => {
|
||||||
|
return (
|
||||||
|
<option
|
||||||
|
key={model.id}
|
||||||
|
value={model.id}
|
||||||
|
selected={settings?.EmbeddingModelPref === model.id}
|
||||||
|
>
|
||||||
|
{model.name}
|
||||||
|
</option>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</optgroup>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="flex flex-col w-60">
|
||||||
|
<div
|
||||||
|
data-tooltip-id="embedding-output-dimensions-tooltip"
|
||||||
|
className="flex gap-x-1 items-center mb-3"
|
||||||
|
>
|
||||||
|
<label className="text-white text-sm font-semibold block">
|
||||||
|
Output dimensions
|
||||||
</label>
|
</label>
|
||||||
<input
|
<Info
|
||||||
type="password"
|
size={16}
|
||||||
name="GeminiEmbeddingApiKey"
|
className="text-theme-text-secondary cursor-pointer"
|
||||||
className="border-none bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
|
||||||
placeholder="Gemini API Key"
|
|
||||||
defaultValue={settings?.GeminiEmbeddingApiKey ? "*".repeat(20) : ""}
|
|
||||||
required={true}
|
|
||||||
autoComplete="off"
|
|
||||||
spellCheck={false}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
<Tooltip
|
||||||
<div className="flex flex-col w-60">
|
id="embedding-output-dimensions-tooltip"
|
||||||
<label className="text-white text-sm font-semibold block mb-3">
|
place="top"
|
||||||
Model Preference
|
delayShow={300}
|
||||||
</label>
|
className="tooltip !text-xs !opacity-100"
|
||||||
<select
|
style={{
|
||||||
name="EmbeddingModelPref"
|
maxWidth: "250px",
|
||||||
required={true}
|
whiteSpace: "normal",
|
||||||
className="border-none bg-theme-settings-input-bg border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
wordWrap: "break-word",
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<optgroup label="Available embedding models">
|
The number of dimensions the resulting output embeddings should have
|
||||||
{DEFAULT_MODELS.map((model) => {
|
if it supports multiple dimensions output.
|
||||||
return (
|
<br />
|
||||||
<option
|
<br /> Leave blank to use the default dimensions for the selected
|
||||||
key={model.id}
|
model.
|
||||||
value={model.id}
|
</Tooltip>
|
||||||
selected={settings?.EmbeddingModelPref === model.id}
|
|
||||||
>
|
|
||||||
{model.name}
|
|
||||||
</option>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</optgroup>
|
|
||||||
</select>
|
|
||||||
</div>
|
</div>
|
||||||
|
<input
|
||||||
|
type="number"
|
||||||
|
name="EmbeddingOutputDimensions"
|
||||||
|
className="border-none bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||||
|
placeholder="Assume default dimensions"
|
||||||
|
min={1}
|
||||||
|
onScroll={(e) => e.target.blur()}
|
||||||
|
defaultValue={settings?.EmbeddingOutputDimensions}
|
||||||
|
required={false}
|
||||||
|
autoComplete="off"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -30,20 +30,70 @@ export default function LocalAiOptions({ settings }) {
|
|||||||
apiKey={apiKey}
|
apiKey={apiKey}
|
||||||
basePath={basePath.value}
|
basePath={basePath.value}
|
||||||
/>
|
/>
|
||||||
|
<div className="flex flex-col w-60">
|
||||||
|
<div className="flex flex-col gap-y-1 mb-2">
|
||||||
|
<div className="flex gap-x-1 items-center">
|
||||||
|
<label className="text-white text-sm font-semibold block">
|
||||||
|
Local AI API Key
|
||||||
|
</label>
|
||||||
|
<Info
|
||||||
|
size={16}
|
||||||
|
data-tooltip-id="localai-api-key-tooltip"
|
||||||
|
className="text-theme-text-secondary cursor-pointer"
|
||||||
|
/>
|
||||||
|
<Tooltip
|
||||||
|
id="localai-api-key-tooltip"
|
||||||
|
place="top"
|
||||||
|
delayShow={300}
|
||||||
|
className="tooltip !text-xs !opacity-100"
|
||||||
|
style={{
|
||||||
|
maxWidth: "250px",
|
||||||
|
whiteSpace: "normal",
|
||||||
|
wordWrap: "break-word",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
The API key for the LocalAI server (if applicable).
|
||||||
|
</Tooltip>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<input
|
||||||
|
type="password"
|
||||||
|
name="LocalAiApiKey"
|
||||||
|
className="border-none bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||||
|
placeholder="sk-mysecretkey"
|
||||||
|
defaultValue={settings?.LocalAiApiKey ? "*".repeat(20) : ""}
|
||||||
|
autoComplete="off"
|
||||||
|
spellCheck={false}
|
||||||
|
onChange={(e) => setApiKeyValue(e.target.value)}
|
||||||
|
onBlur={() => setApiKey(apiKeyValue)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="w-full flex items-center gap-[36px] mt-1.5">
|
||||||
<div className="flex flex-col w-60">
|
<div className="flex flex-col w-60">
|
||||||
<div
|
<div
|
||||||
data-tooltip-place="top"
|
data-tooltip-place="top"
|
||||||
data-tooltip-id="max-embedding-chunk-length-tooltip"
|
data-tooltip-id="max-embedding-chunk-length-tooltip"
|
||||||
className="flex gap-x-1 items-center mb-3"
|
className="flex gap-x-1 items-center mb-3"
|
||||||
>
|
>
|
||||||
|
<label className="text-white text-sm font-semibold block">
|
||||||
|
Max embedding chunk length
|
||||||
|
</label>
|
||||||
<Info
|
<Info
|
||||||
size={16}
|
size={16}
|
||||||
className="text-theme-text-secondary cursor-pointer"
|
className="text-theme-text-secondary cursor-pointer"
|
||||||
/>
|
/>
|
||||||
<label className="text-white text-sm font-semibold block">
|
<Tooltip
|
||||||
Max embedding chunk length
|
id="max-embedding-chunk-length-tooltip"
|
||||||
</label>
|
place="top"
|
||||||
<Tooltip id="max-embedding-chunk-length-tooltip">
|
delayShow={300}
|
||||||
|
className="tooltip !text-xs !opacity-100"
|
||||||
|
style={{
|
||||||
|
maxWidth: "250px",
|
||||||
|
whiteSpace: "normal",
|
||||||
|
wordWrap: "break-word",
|
||||||
|
}}
|
||||||
|
>
|
||||||
Maximum length of text chunks, in characters, for embedding.
|
Maximum length of text chunks, in characters, for embedding.
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</div>
|
</div>
|
||||||
@ -59,23 +109,47 @@ export default function LocalAiOptions({ settings }) {
|
|||||||
autoComplete="off"
|
autoComplete="off"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex flex-col w-60">
|
<div className="flex flex-col w-60">
|
||||||
<div className="flex flex-col gap-y-1 mb-2">
|
<div
|
||||||
<label className="text-white text-sm font-semibold flex items-center gap-x-2">
|
data-tooltip-id="embedding-output-dimensions-tooltip"
|
||||||
Local AI API Key{" "}
|
className="flex gap-x-1 items-center mb-3"
|
||||||
<p className="!text-xs !italic !font-thin">optional</p>
|
>
|
||||||
|
<label className="text-white text-sm font-semibold block">
|
||||||
|
Output dimensions
|
||||||
</label>
|
</label>
|
||||||
|
<Info
|
||||||
|
size={16}
|
||||||
|
className="text-theme-text-secondary cursor-pointer"
|
||||||
|
/>
|
||||||
|
<Tooltip
|
||||||
|
id="embedding-output-dimensions-tooltip"
|
||||||
|
place="top"
|
||||||
|
delayShow={300}
|
||||||
|
className="tooltip !text-xs !opacity-100"
|
||||||
|
style={{
|
||||||
|
maxWidth: "250px",
|
||||||
|
whiteSpace: "normal",
|
||||||
|
wordWrap: "break-word",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
The number of dimensions the resulting output embeddings should
|
||||||
|
have if it supports multiple dimensions output.
|
||||||
|
<br />
|
||||||
|
<br /> Leave blank to use the default dimensions for the selected
|
||||||
|
model.
|
||||||
|
</Tooltip>
|
||||||
</div>
|
</div>
|
||||||
<input
|
<input
|
||||||
type="password"
|
type="number"
|
||||||
name="LocalAiApiKey"
|
name="EmbeddingOutputDimensions"
|
||||||
className="border-none bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
className="border-none bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||||
placeholder="sk-mysecretkey"
|
placeholder="Assume default dimensions"
|
||||||
defaultValue={settings?.LocalAiApiKey ? "*".repeat(20) : ""}
|
min={1}
|
||||||
|
onScroll={(e) => e.target.blur()}
|
||||||
|
defaultValue={settings?.EmbeddingOutputDimensions}
|
||||||
|
required={false}
|
||||||
autoComplete="off"
|
autoComplete="off"
|
||||||
spellCheck={false}
|
|
||||||
onChange={(e) => setApiKeyValue(e.target.value)}
|
|
||||||
onBlur={() => setApiKey(apiKeyValue)}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -75,7 +75,7 @@ export function ToggleSidebarButton({ showSidebar, setShowSidebar }) {
|
|||||||
<>
|
<>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className={`hidden md:block border-none bg-transparent outline-none ring-0 transition-left duration-500 ${showSidebar ? "left-[247px]" : "absolute top-[20px] left-[30px] z-10"}`}
|
className={`hidden md:block border-none bg-transparent outline-none ring-0 absolute transition-all duration-500 z-10 ${showSidebar ? "top-[18px] left-[248px]" : "top-[20px] left-[30px]"}`}
|
||||||
onClick={() => setShowSidebar((prev) => !prev)}
|
onClick={() => setShowSidebar((prev) => !prev)}
|
||||||
data-tooltip-id="sidebar-toggle"
|
data-tooltip-id="sidebar-toggle"
|
||||||
data-tooltip-content={
|
data-tooltip-content={
|
||||||
|
|||||||
@ -34,39 +34,41 @@ export default function Sidebar() {
|
|||||||
width: showSidebar ? "292px" : "0px",
|
width: showSidebar ? "292px" : "0px",
|
||||||
paddingLeft: showSidebar ? "0px" : "16px",
|
paddingLeft: showSidebar ? "0px" : "16px",
|
||||||
}}
|
}}
|
||||||
className="transition-all duration-500"
|
className="relative transition-all duration-500"
|
||||||
>
|
>
|
||||||
<div className="flex shrink-0 w-full justify-center my-[18px]">
|
{canToggleSidebar && (
|
||||||
<div className="flex justify-between w-[250px] min-w-[250px]">
|
<ToggleSidebarButton
|
||||||
<Link to={paths.home()} aria-label="Home">
|
showSidebar={showSidebar}
|
||||||
<img
|
setShowSidebar={setShowSidebar}
|
||||||
src={logo}
|
/>
|
||||||
alt="Logo"
|
)}
|
||||||
className={`rounded max-h-[24px] object-contain transition-opacity duration-500 ${showSidebar ? "opacity-100" : "opacity-0"}`}
|
<div className="overflow-hidden h-full">
|
||||||
/>
|
<div className="flex shrink-0 w-full justify-center my-[18px]">
|
||||||
</Link>
|
<div className="flex w-[250px] min-w-[250px]">
|
||||||
{canToggleSidebar && (
|
<Link to={paths.home()} aria-label="Home">
|
||||||
<ToggleSidebarButton
|
<img
|
||||||
showSidebar={showSidebar}
|
src={logo}
|
||||||
setShowSidebar={setShowSidebar}
|
alt="Logo"
|
||||||
/>
|
className={`rounded max-h-[24px] object-contain transition-opacity duration-500 ${showSidebar ? "opacity-100" : "opacity-0"}`}
|
||||||
)}
|
/>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div
|
||||||
<div
|
ref={sidebarRef}
|
||||||
ref={sidebarRef}
|
className="relative m-[16px] rounded-[16px] bg-theme-bg-sidebar border-[2px] border-theme-sidebar-border light:border-none min-w-[250px] p-[10px] h-[calc(100%-76px)]"
|
||||||
className="relative m-[16px] rounded-[16px] bg-theme-bg-sidebar border-[2px] border-theme-sidebar-border light:border-none min-w-[250px] p-[10px] h-[calc(100%-76px)]"
|
>
|
||||||
>
|
<div className="flex flex-col h-full overflow-hidden">
|
||||||
<div className="flex flex-col h-full overflow-hidden">
|
<div className="flex-grow flex flex-col min-w-[235px] min-h-0">
|
||||||
<div className="flex-grow flex flex-col min-w-[235px] min-h-0">
|
<div className="relative h-[calc(100%-60px)] flex flex-col w-full justify-between pt-[10px] overflow-y-scroll no-scroll">
|
||||||
<div className="relative h-[calc(100%-60px)] flex flex-col w-full justify-between pt-[10px] overflow-y-scroll no-scroll">
|
<div className="flex flex-col gap-y-[14px]">
|
||||||
<div className="flex flex-col gap-y-[14px]">
|
<SearchBox user={user} showNewWsModal={showNewWsModal} />
|
||||||
<SearchBox user={user} showNewWsModal={showNewWsModal} />
|
<ActiveWorkspaces />
|
||||||
<ActiveWorkspaces />
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="absolute bottom-0 left-0 right-0 pb-3 rounded-b-[16px] bg-theme-bg-sidebar bg-opacity-80 backdrop-filter backdrop-blur-md z-10">
|
||||||
|
<Footer />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
<div className="absolute bottom-0 left-0 right-0 pb-3 rounded-b-[16px] bg-theme-bg-sidebar bg-opacity-80 backdrop-filter backdrop-blur-md z-10">
|
|
||||||
<Footer />
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -233,6 +233,8 @@ const SystemSettings = {
|
|||||||
embeddingEngine === "native"
|
embeddingEngine === "native"
|
||||||
? NativeEmbedder._getEmbeddingModel()
|
? NativeEmbedder._getEmbeddingModel()
|
||||||
: process.env.EMBEDDING_MODEL_PREF,
|
: process.env.EMBEDDING_MODEL_PREF,
|
||||||
|
EmbeddingOutputDimensions:
|
||||||
|
process.env.EMBEDDING_OUTPUT_DIMENSIONS || null,
|
||||||
EmbeddingModelMaxChunkLength:
|
EmbeddingModelMaxChunkLength:
|
||||||
process.env.EMBEDDING_MODEL_MAX_CHUNK_LENGTH,
|
process.env.EMBEDDING_MODEL_MAX_CHUNK_LENGTH,
|
||||||
OllamaEmbeddingBatchSize: process.env.OLLAMA_EMBEDDING_BATCH_SIZE || 1,
|
OllamaEmbeddingBatchSize: process.env.OLLAMA_EMBEDDING_BATCH_SIZE || 1,
|
||||||
|
|||||||
@ -23,7 +23,10 @@ class GeminiEmbedder {
|
|||||||
// https://ai.google.dev/gemini-api/docs/models/gemini#text-embedding-and-embedding
|
// https://ai.google.dev/gemini-api/docs/models/gemini#text-embedding-and-embedding
|
||||||
this.embeddingMaxChunkLength = MODEL_MAP[this.model] || 2_048;
|
this.embeddingMaxChunkLength = MODEL_MAP[this.model] || 2_048;
|
||||||
this.log(
|
this.log(
|
||||||
`Initialized with ${this.model} - Max Size: ${this.embeddingMaxChunkLength}`
|
`Initialized with ${this.model} - Max Size: ${this.embeddingMaxChunkLength}` +
|
||||||
|
(this.outputDimensions
|
||||||
|
? ` - Output Dimensions: ${this.outputDimensions}`
|
||||||
|
: " Assuming default output dimensions")
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -31,6 +34,16 @@ class GeminiEmbedder {
|
|||||||
console.log(`\x1b[36m[${this.className}]\x1b[0m ${text}`, ...args);
|
console.log(`\x1b[36m[${this.className}]\x1b[0m ${text}`, ...args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get outputDimensions() {
|
||||||
|
if (
|
||||||
|
process.env.EMBEDDING_OUTPUT_DIMENSIONS &&
|
||||||
|
!isNaN(process.env.EMBEDDING_OUTPUT_DIMENSIONS) &&
|
||||||
|
process.env.EMBEDDING_OUTPUT_DIMENSIONS > 0
|
||||||
|
)
|
||||||
|
return parseInt(process.env.EMBEDDING_OUTPUT_DIMENSIONS);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Embeds a single text input
|
* Embeds a single text input
|
||||||
* @param {string|string[]} textInput - The text to embed
|
* @param {string|string[]} textInput - The text to embed
|
||||||
@ -62,6 +75,7 @@ class GeminiEmbedder {
|
|||||||
.create({
|
.create({
|
||||||
model: this.model,
|
model: this.model,
|
||||||
input: chunk,
|
input: chunk,
|
||||||
|
dimensions: this.outputDimensions,
|
||||||
})
|
})
|
||||||
.then((result) => {
|
.then((result) => {
|
||||||
resolve({ data: result?.data, error: null });
|
resolve({ data: result?.data, error: null });
|
||||||
|
|||||||
@ -7,7 +7,9 @@ class LocalAiEmbedder {
|
|||||||
if (!process.env.EMBEDDING_MODEL_PREF)
|
if (!process.env.EMBEDDING_MODEL_PREF)
|
||||||
throw new Error("No embedding model was set.");
|
throw new Error("No embedding model was set.");
|
||||||
|
|
||||||
|
this.className = "LocalAiEmbedder";
|
||||||
const { OpenAI: OpenAIApi } = require("openai");
|
const { OpenAI: OpenAIApi } = require("openai");
|
||||||
|
this.model = process.env.EMBEDDING_MODEL_PREF;
|
||||||
this.openai = new OpenAIApi({
|
this.openai = new OpenAIApi({
|
||||||
baseURL: process.env.EMBEDDING_BASE_PATH,
|
baseURL: process.env.EMBEDDING_BASE_PATH,
|
||||||
apiKey: process.env.LOCAL_AI_API_KEY ?? null,
|
apiKey: process.env.LOCAL_AI_API_KEY ?? null,
|
||||||
@ -16,6 +18,27 @@ class LocalAiEmbedder {
|
|||||||
// Limit of how many strings we can process in a single pass to stay with resource or network limits
|
// Limit of how many strings we can process in a single pass to stay with resource or network limits
|
||||||
this.maxConcurrentChunks = 50;
|
this.maxConcurrentChunks = 50;
|
||||||
this.embeddingMaxChunkLength = maximumChunkLength();
|
this.embeddingMaxChunkLength = maximumChunkLength();
|
||||||
|
|
||||||
|
this.log(
|
||||||
|
`Initialized with ${this.model} - Max Size: ${this.embeddingMaxChunkLength}` +
|
||||||
|
(this.outputDimensions
|
||||||
|
? ` - Output Dimensions: ${this.outputDimensions}`
|
||||||
|
: " Assuming default output dimensions")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
log(text, ...args) {
|
||||||
|
console.log(`\x1b[36m[${this.className}]\x1b[0m ${text}`, ...args);
|
||||||
|
}
|
||||||
|
|
||||||
|
get outputDimensions() {
|
||||||
|
if (
|
||||||
|
process.env.EMBEDDING_OUTPUT_DIMENSIONS &&
|
||||||
|
!isNaN(process.env.EMBEDDING_OUTPUT_DIMENSIONS) &&
|
||||||
|
process.env.EMBEDDING_OUTPUT_DIMENSIONS > 0
|
||||||
|
)
|
||||||
|
return parseInt(process.env.EMBEDDING_OUTPUT_DIMENSIONS);
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
async embedTextInput(textInput) {
|
async embedTextInput(textInput) {
|
||||||
@ -32,8 +55,9 @@ class LocalAiEmbedder {
|
|||||||
new Promise((resolve) => {
|
new Promise((resolve) => {
|
||||||
this.openai.embeddings
|
this.openai.embeddings
|
||||||
.create({
|
.create({
|
||||||
model: process.env.EMBEDDING_MODEL_PREF,
|
model: this.model,
|
||||||
input: chunk,
|
input: chunk,
|
||||||
|
dimensions: this.outputDimensions,
|
||||||
})
|
})
|
||||||
.then((result) => {
|
.then((result) => {
|
||||||
resolve({ data: result?.data, error: null });
|
resolve({ data: result?.data, error: null });
|
||||||
|
|||||||
@ -307,6 +307,10 @@ const KEY_MAPPING = {
|
|||||||
envKey: "EMBEDDING_MODEL_MAX_CHUNK_LENGTH",
|
envKey: "EMBEDDING_MODEL_MAX_CHUNK_LENGTH",
|
||||||
checks: [nonZero],
|
checks: [nonZero],
|
||||||
},
|
},
|
||||||
|
EmbeddingOutputDimensions: {
|
||||||
|
envKey: "EMBEDDING_OUTPUT_DIMENSIONS",
|
||||||
|
checks: [],
|
||||||
|
},
|
||||||
OllamaEmbeddingBatchSize: {
|
OllamaEmbeddingBatchSize: {
|
||||||
envKey: "OLLAMA_EMBEDDING_BATCH_SIZE",
|
envKey: "OLLAMA_EMBEDDING_BATCH_SIZE",
|
||||||
checks: [nonZero],
|
checks: [nonZero],
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user