Merge branch 'master' of github.com:Mintplex-Labs/anything-llm into render

This commit is contained in:
timothycarambat 2024-07-11 15:58:21 -07:00
commit a56c124543
88 changed files with 502 additions and 634 deletions

View File

@ -29,11 +29,13 @@
"Milvus",
"Mintplex",
"moderations",
"numpages",
"Ollama",
"Oobabooga",
"openai",
"opendocument",
"openrouter",
"pagerender",
"Qdrant",
"searxng",
"Serper",

View File

@ -37,7 +37,7 @@
"node-html-parser": "^6.1.13",
"officeparser": "^4.0.5",
"openai": "4.38.5",
"pdfjs-dist": "3.4.120",
"pdf-parse": "^1.1.1",
"puppeteer": "~21.5.2",
"slugify": "^1.6.6",
"url-pattern": "^1.0.3",

View File

@ -0,0 +1,62 @@
const fs = require("fs").promises;
const pdf = require("pdf-parse");
class PDFLoader {
constructor(filePath, { splitPages = true } = {}) {
this.filePath = filePath;
this.splitPages = splitPages;
}
async load() {
const buffer = await fs.readFile(this.filePath);
const options = {
pagerender: this.splitPages ? this.renderPage : null,
};
const { text, numpages, info, metadata, version } = await pdf(
buffer,
options
);
if (!this.splitPages) {
return [
{
pageContent: text.trim(),
metadata: {
source: this.filePath,
pdf: { version, info, metadata, totalPages: numpages },
},
},
];
}
return this.pages.map((pageContent, index) => ({
pageContent: pageContent.trim(),
metadata: {
source: this.filePath,
pdf: { version, info, metadata, totalPages: numpages },
loc: { pageNumber: index + 1 },
},
}));
}
pages = [];
renderPage = async (pageData) => {
const textContent = await pageData.getTextContent();
let lastY,
text = "";
for (const item of textContent.items) {
if (lastY !== item.transform[5] && lastY !== undefined) {
text += "\n";
}
text += item.str;
lastY = item.transform[5];
}
this.pages.push(text);
return text;
};
}
module.exports = PDFLoader;

View File

@ -3,29 +3,28 @@ const {
createdDate,
trashFile,
writeToServerDocuments,
} = require("../../utils/files");
const { tokenizeString } = require("../../utils/tokenizer");
} = require("../../../utils/files");
const { tokenizeString } = require("../../../utils/tokenizer");
const { default: slugify } = require("slugify");
const PDFLoader = require("./PDFLoader");
async function asPdf({ fullFilePath = "", filename = "" }) {
const pdfLoader = new PDFLoader(fullFilePath, {
splitPages: true,
});
async function asPDF({ fullFilePath = "", filename = "" }) {
const pdfjsLib = await import("pdfjs-dist");
console.log(`-- Working ${filename} --`);
const loadingTask = pdfjsLib.default.getDocument(fullFilePath);
const pdf = await loadingTask.promise;
const numPages = pdf.numPages;
const pageContent = [];
const docs = await pdfLoader.load();
for (let i = 1; i <= numPages; i++) {
console.log(`-- Parsing content from pg ${i} --`);
const page = await pdf.getPage(i);
const content = await page.getTextContent();
const text = content.items.map((item) => item.str).join(" ");
if (text.length) {
pageContent.push(text);
}
for (const doc of docs) {
console.log(
`-- Parsing content from pg ${
doc.metadata?.loc?.pageNumber || "unknown"
} --`
);
if (!doc.pageContent || !doc.pageContent.length) continue;
pageContent.push(doc.pageContent);
}
if (!pageContent.length) {
@ -38,15 +37,13 @@ async function asPDF({ fullFilePath = "", filename = "" }) {
};
}
const content = pageContent.join(" ");
const metadata = await pdf.getMetadata();
const content = pageContent.join("");
const data = {
id: v4(),
url: "file://" + fullFilePath,
title: filename,
docAuthor: metadata?.info?.Creator || "no author found",
description: metadata?.info?.Title || "No description found.",
docAuthor: docs[0]?.metadata?.pdf?.info?.Creator || "no author found",
description: docs[0]?.metadata?.pdf?.info?.Title || "No description found.",
docSource: "pdf file uploaded by the user.",
chunkSource: "",
published: createdDate(fullFilePath),
@ -64,4 +61,4 @@ async function asPDF({ fullFilePath = "", filename = "" }) {
return { success: true, reason: null, documents: [document] };
}
module.exports = asPDF;
module.exports = asPdf;

View File

@ -33,7 +33,7 @@ const SUPPORTED_FILETYPE_CONVERTERS = {
".rst": "./convert/asTxt.js",
".html": "./convert/asTxt.js",
".pdf": "./convert/asPDF.js",
".pdf": "./convert/asPDF/index.js",
".docx": "./convert/asDocx.js",
".pptx": "./convert/asOfficeMime.js",

View File

@ -122,7 +122,7 @@
"@langchain/core" "~0.1"
js-tiktoken "^1.0.11"
"@mapbox/node-pre-gyp@^1.0.0", "@mapbox/node-pre-gyp@^1.0.11":
"@mapbox/node-pre-gyp@^1.0.11":
version "1.0.11"
resolved "https://registry.yarnpkg.com/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz#417db42b7f5323d79e93b34a6d7a2a12c0df43fa"
integrity sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==
@ -662,15 +662,6 @@ camelcase@6:
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a"
integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==
canvas@^2.11.0:
version "2.11.2"
resolved "https://registry.yarnpkg.com/canvas/-/canvas-2.11.2.tgz#553d87b1e0228c7ac0fc72887c3adbac4abbd860"
integrity sha512-ItanGBMrmRV7Py2Z+Xhs7cT+FNt5K0vPL4p9EZ/UX/Mu7hFbkxSjKF2KVtPwX7UYWp7dRKnrTvReflgrItJbdw==
dependencies:
"@mapbox/node-pre-gyp" "^1.0.0"
nan "^2.17.0"
simple-get "^3.0.3"
chalk@^2.4.2:
version "2.4.2"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
@ -936,13 +927,6 @@ decamelize@1.2.0:
resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290"
integrity sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==
decompress-response@^4.2.0:
version "4.2.1"
resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-4.2.1.tgz#414023cc7a302da25ce2ec82d0d5238ccafd8986"
integrity sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==
dependencies:
mimic-response "^2.0.0"
decompress-response@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc"
@ -2237,11 +2221,6 @@ mime@^3.0.0:
resolved "https://registry.yarnpkg.com/mime/-/mime-3.0.0.tgz#b374550dca3a0c18443b0c950a6a58f1931cf7a7"
integrity sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==
mimic-response@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-2.1.0.tgz#d13763d35f613d09ec37ebb30bac0469c0ee8f43"
integrity sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==
mimic-response@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9"
@ -2375,11 +2354,6 @@ mustache@^4.2.0:
resolved "https://registry.yarnpkg.com/mustache/-/mustache-4.2.0.tgz#e5892324d60a12ec9c2a73359edca52972bf6f64"
integrity sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==
nan@^2.17.0:
version "2.20.0"
resolved "https://registry.yarnpkg.com/nan/-/nan-2.20.0.tgz#08c5ea813dd54ed16e5bd6505bf42af4f7838ca3"
integrity sha512-bk3gXBZDGILuuo/6sKtr0DQmSThYHLtNCdSdXk9YkxD/jK6X2vmCyyXBBxyqZ4XcnzTyYEAThfX3DCEnLf6igw==
napi-build-utils@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/napi-build-utils/-/napi-build-utils-1.0.2.tgz#b1fddc0b2c46e380a0b7a76f984dd47c41a13806"
@ -2715,18 +2689,6 @@ path-type@^4.0.0:
resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b"
integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==
path2d-polyfill@^2.0.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/path2d-polyfill/-/path2d-polyfill-2.1.1.tgz#6098b7bf2fc24c306c6377bcd558b17ba437ea27"
integrity sha512-4Rka5lN+rY/p0CdD8+E+BFv51lFaFvJOrlOhyQ+zjzyQrzyh3ozmxd1vVGGDdIbUFSBtIZLSnspxTgPT0iJhvA==
dependencies:
path2d "0.1.1"
path2d@0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/path2d/-/path2d-0.1.1.tgz#d3c3886cd2252fb2a7830c27ea7bb9a862d937ea"
integrity sha512-/+S03c8AGsDYKKBtRDqieTJv2GlkMb0bWjnqOgtF6MkjdUQ9a8ARAtxWf9NgKLGm2+WQr6+/tqJdU8HNGsIDoA==
pdf-parse@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/pdf-parse/-/pdf-parse-1.1.1.tgz#745e07408679548b3995ff896fd38e96e19d14a7"
@ -2735,16 +2697,6 @@ pdf-parse@^1.1.1:
debug "^3.1.0"
node-ensure "^0.0.0"
pdfjs-dist@3.4.120:
version "3.4.120"
resolved "https://registry.yarnpkg.com/pdfjs-dist/-/pdfjs-dist-3.4.120.tgz#6f4222117157498f179c95dc4569fad6336a8fdd"
integrity sha512-B1hw9ilLG4m/jNeFA0C2A0PZydjxslP8ylU+I4XM7Bzh/xWETo9EiBV848lh0O0hLut7T6lK1V7cpAXv5BhxWw==
dependencies:
path2d-polyfill "^2.0.1"
web-streams-polyfill "^3.2.1"
optionalDependencies:
canvas "^2.11.0"
peberminta@^0.9.0:
version "0.9.0"
resolved "https://registry.yarnpkg.com/peberminta/-/peberminta-0.9.0.tgz#8ec9bc0eb84b7d368126e71ce9033501dca2a352"
@ -3175,15 +3127,6 @@ simple-concat@^1.0.0:
resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.1.tgz#f46976082ba35c2263f1c8ab5edfe26c41c9552f"
integrity sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==
simple-get@^3.0.3:
version "3.1.1"
resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-3.1.1.tgz#cc7ba77cfbe761036fbfce3d021af25fc5584d55"
integrity sha512-CQ5LTKGfCpvE1K0n2us+kuMPbk/q0EKl82s4aheV9oXjFEz6W/Y7oQFVJuU6QG77hRT4Ghb5RURteF5vnWjupA==
dependencies:
decompress-response "^4.2.0"
once "^1.3.1"
simple-concat "^1.0.0"
simple-get@^4.0.0, simple-get@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-4.0.1.tgz#4a39db549287c979d352112fa03fd99fd6bc3543"

View File

@ -1,15 +1,15 @@
export default function AzureAiOptions({ settings }) {
return (
<div className="w-full flex flex-col gap-y-4">
<div className="w-full flex items-center gap-4">
<div className="w-full flex items-center gap-[36px] mt-1.5">
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
Azure Service Endpoint
</label>
<input
type="url"
name="AzureOpenAiEndpoint"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="https://my-azure.openai.azure.com"
defaultValue={settings?.AzureOpenAiEndpoint}
required={true}
@ -19,13 +19,13 @@ export default function AzureAiOptions({ settings }) {
</div>
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
API Key
</label>
<input
type="password"
name="AzureOpenAiKey"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="Azure OpenAI API Key"
defaultValue={settings?.AzureOpenAiKey ? "*".repeat(20) : ""}
required={true}
@ -35,13 +35,13 @@ export default function AzureAiOptions({ settings }) {
</div>
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
Embedding Deployment Name
</label>
<input
type="text"
name="AzureOpenAiEmbeddingModelPref"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="Azure OpenAI embedding model deployment name"
defaultValue={settings?.AzureOpenAiEmbeddingModelPref}
required={true}

View File

@ -1,15 +1,15 @@
export default function CohereEmbeddingOptions({ settings }) {
return (
<div className="w-full flex flex-col gap-y-4">
<div className="w-full flex items-center gap-4">
<div className="w-full flex items-center gap-[36px] mt-1.5">
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
API Key
</label>
<input
type="password"
name="CohereApiKey"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="Cohere API Key"
defaultValue={settings?.CohereApiKey ? "*".repeat(20) : ""}
required={true}
@ -18,7 +18,7 @@ export default function CohereEmbeddingOptions({ settings }) {
/>
</div>
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
Model Preference
</label>
<select

View File

@ -1,15 +1,15 @@
export default function GenericOpenAiEmbeddingOptions({ settings }) {
return (
<div className="w-full flex flex-col gap-y-4">
<div className="w-full flex items-center gap-4 flex-wrap">
<div className="w-full flex flex-col gap-y-7">
<div className="w-full flex items-center gap-[36px] mt-1.5 flex-wrap">
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
Base URL
</label>
<input
type="url"
name="EmbeddingBasePath"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="https://api.openai.com/v1"
defaultValue={settings?.EmbeddingBasePath}
required={true}
@ -18,13 +18,13 @@ export default function GenericOpenAiEmbeddingOptions({ settings }) {
/>
</div>
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
Embedding Model
</label>
<input
type="text"
name="EmbeddingModelPref"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="text-embedding-ada-002"
defaultValue={settings?.EmbeddingModelPref}
required={true}
@ -33,13 +33,13 @@ export default function GenericOpenAiEmbeddingOptions({ settings }) {
/>
</div>
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
Max embedding chunk length
</label>
<input
type="number"
name="EmbeddingModelMaxChunkLength"
className="bg-zinc-900 text-white placeholder-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="bg-zinc-900 text-white placeholder-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="8192"
min={1}
onScroll={(e) => e.target.blur()}
@ -49,7 +49,7 @@ export default function GenericOpenAiEmbeddingOptions({ settings }) {
/>
</div>
</div>
<div className="w-full flex items-center gap-4">
<div className="w-full flex items-center gap-[36px]">
<div className="flex flex-col w-60">
<div className="flex flex-col gap-y-1 mb-4">
<label className="text-white text-sm font-semibold flex items-center gap-x-2">
@ -59,7 +59,7 @@ export default function GenericOpenAiEmbeddingOptions({ settings }) {
<input
type="password"
name="GenericOpenAiEmbeddingApiKey"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="bg-zinc-900 text-white placeholder:text-white/20 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?.GenericOpenAiEmbeddingApiKey ? "*".repeat(20) : ""

View File

@ -28,8 +28,8 @@ export default function LMStudioEmbeddingOptions({ settings }) {
};
return (
<div className="w-full flex flex-col gap-y-4">
<div className="w-full flex items-start gap-4">
<div className="w-full flex flex-col gap-y-7">
<div className="w-full flex items-start gap-[36px] mt-1.5">
<LMStudioModelSelection settings={settings} basePath={basePath.value} />
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-2">
@ -38,7 +38,7 @@ export default function LMStudioEmbeddingOptions({ settings }) {
<input
type="number"
name="EmbeddingModelMaxChunkLength"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="8192"
min={1}
value={maxChunkLength}
@ -94,7 +94,7 @@ export default function LMStudioEmbeddingOptions({ settings }) {
<input
type="url"
name="EmbeddingBasePath"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="http://localhost:1234/v1"
value={basePathValue.value}
required={true}

View File

@ -10,16 +10,16 @@ export default function LiteLLMOptions({ settings }) {
const [apiKey, setApiKey] = useState(settings?.LiteLLMAPIKey);
return (
<div className="w-full flex flex-col gap-y-4">
<div className="w-full flex items-center gap-4">
<div className="w-full flex flex-col gap-y-7">
<div className="w-full flex items-center gap-[36px] mt-1.5">
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
Base URL
</label>
<input
type="url"
name="LiteLLMBasePath"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="http://127.0.0.1:4000"
defaultValue={settings?.LiteLLMBasePath}
required={true}
@ -35,13 +35,13 @@ export default function LiteLLMOptions({ settings }) {
apiKey={apiKey}
/>
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
Max embedding chunk length
</label>
<input
type="number"
name="EmbeddingModelMaxChunkLength"
className="bg-zinc-900 text-white placeholder-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="bg-zinc-900 text-white placeholder-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="8192"
min={1}
onScroll={(e) => e.target.blur()}
@ -51,7 +51,7 @@ export default function LiteLLMOptions({ settings }) {
/>
</div>
</div>
<div className="w-full flex items-center gap-4">
<div className="w-full flex items-center gap-[36px]">
<div className="flex flex-col w-60">
<div className="flex flex-col gap-y-1 mb-4">
<label className="text-white text-sm font-semibold flex items-center gap-x-2">
@ -61,7 +61,7 @@ export default function LiteLLMOptions({ settings }) {
<input
type="password"
name="LiteLLMAPIKey"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="bg-zinc-900 text-white placeholder:text-white/20 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?.LiteLLMAPIKey ? "*".repeat(20) : ""}
autoComplete="off"
@ -101,7 +101,7 @@ function LiteLLMModelSelection({ settings, basePath = null, apiKey = null }) {
if (loading || customModels.length == 0) {
return (
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
Embedding Model Selection
</label>
<select
@ -122,7 +122,7 @@ function LiteLLMModelSelection({ settings, basePath = null, apiKey = null }) {
return (
<div className="flex flex-col w-60">
<div className="flex items-center">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
Embedding Model Selection
</label>
<EmbeddingModelTooltip />

View File

@ -10,16 +10,16 @@ export default function LocalAiOptions({ settings }) {
const [apiKey, setApiKey] = useState(settings?.LocalAiApiKey);
return (
<div className="w-full flex flex-col gap-y-4">
<div className="w-full flex items-center gap-4">
<div className="w-full flex flex-col gap-y-7">
<div className="w-full flex items-center gap-[36px] mt-1.5">
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
LocalAI Base URL
</label>
<input
type="url"
name="EmbeddingBasePath"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="http://localhost:8080/v1"
defaultValue={settings?.EmbeddingBasePath}
onChange={(e) => setBasePathValue(e.target.value)}
@ -35,13 +35,13 @@ export default function LocalAiOptions({ settings }) {
basePath={basePath}
/>
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
Max embedding chunk length
</label>
<input
type="number"
name="EmbeddingModelMaxChunkLength"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="1000"
min={1}
onScroll={(e) => e.target.blur()}
@ -51,7 +51,7 @@ export default function LocalAiOptions({ settings }) {
/>
</div>
</div>
<div className="w-full flex items-center gap-4">
<div className="w-full flex items-center gap-[36px]">
<div className="flex flex-col w-60">
<div className="flex flex-col gap-y-1 mb-4">
<label className="text-white text-sm font-semibold flex items-center gap-x-2">
@ -62,7 +62,7 @@ export default function LocalAiOptions({ settings }) {
<input
type="password"
name="LocalAiApiKey"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="bg-zinc-900 text-white placeholder:text-white/20 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"
@ -102,7 +102,7 @@ function LocalAIModelSelection({ settings, apiKey = null, basePath = null }) {
if (loading || customModels.length == 0) {
return (
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
Embedding Model Name
</label>
<select
@ -122,7 +122,7 @@ function LocalAIModelSelection({ settings, apiKey = null, basePath = null }) {
return (
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
Embedding Model Name
</label>
<select

View File

@ -28,8 +28,8 @@ export default function OllamaEmbeddingOptions({ settings }) {
};
return (
<div className="w-full flex flex-col gap-y-4">
<div className="w-full flex items-start gap-4">
<div className="w-full flex flex-col gap-y-7">
<div className="w-full flex items-start gap-[36px] mt-1.5">
<OllamaEmbeddingModelSelection
settings={settings}
basePath={basePath.value}
@ -41,7 +41,7 @@ export default function OllamaEmbeddingOptions({ settings }) {
<input
type="number"
name="EmbeddingModelMaxChunkLength"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="8192"
min={1}
value={maxChunkLength}
@ -97,7 +97,7 @@ export default function OllamaEmbeddingOptions({ settings }) {
<input
type="url"
name="EmbeddingBasePath"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="http://127.0.0.1:11434"
value={basePathValue.value}
required={true}

View File

@ -1,15 +1,15 @@
export default function OpenAiOptions({ settings }) {
return (
<div className="w-full flex flex-col gap-y-4">
<div className="w-full flex items-center gap-4">
<div className="w-full flex items-center gap-[36px] mt-1.5">
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
API Key
</label>
<input
type="password"
name="OpenAiKey"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="OpenAI API Key"
defaultValue={settings?.OpenAiKey ? "*".repeat(20) : ""}
required={true}
@ -18,7 +18,7 @@ export default function OpenAiOptions({ settings }) {
/>
</div>
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
Model Preference
</label>
<select

View File

@ -1,15 +1,15 @@
export default function VoyageAiOptions({ settings }) {
return (
<div className="w-full flex flex-col gap-y-4">
<div className="w-full flex items-center gap-4">
<div className="w-full flex items-center gap-[36px] mt-1.5">
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
API Key
</label>
<input
type="password"
name="VoyageAiApiKey"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="Voyage AI API Key"
defaultValue={settings?.VoyageAiApiKey ? "*".repeat(20) : ""}
required={true}
@ -18,7 +18,7 @@ export default function VoyageAiOptions({ settings }) {
/>
</div>
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
Model Preference
</label>
<select

View File

@ -1,15 +1,15 @@
export default function AnthropicAiOptions({ settings }) {
return (
<div className="w-full flex flex-col">
<div className="w-full flex items-center gap-4">
<div className="w-full flex items-center gap-[36px] mt-1.5">
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
Anthropic API Key
</label>
<input
type="password"
name="AnthropicApiKey"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="Anthropic Claude-2 API Key"
defaultValue={settings?.AnthropicApiKey ? "*".repeat(20) : ""}
required={true}
@ -20,7 +20,7 @@ export default function AnthropicAiOptions({ settings }) {
{!settings?.credentialsOnly && (
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
Chat Model Selection
</label>
<select

View File

@ -1,15 +1,15 @@
export default function AzureAiOptions({ settings }) {
return (
<div className="w-full flex flex-col gap-y-4">
<div className="w-full flex items-center gap-4">
<div className="w-full flex flex-col gap-y-7 mt-1.5">
<div className="w-full flex items-center gap-[36px]">
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
Azure Service Endpoint
</label>
<input
type="url"
name="AzureOpenAiEndpoint"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="https://my-azure.openai.azure.com"
defaultValue={settings?.AzureOpenAiEndpoint}
required={true}
@ -19,13 +19,13 @@ export default function AzureAiOptions({ settings }) {
</div>
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
API Key
</label>
<input
type="password"
name="AzureOpenAiKey"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="Azure OpenAI API Key"
defaultValue={settings?.AzureOpenAiKey ? "*".repeat(20) : ""}
required={true}
@ -35,13 +35,13 @@ export default function AzureAiOptions({ settings }) {
</div>
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
Chat Deployment Name
</label>
<input
type="text"
name="AzureOpenAiModelPref"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="Azure OpenAI chat model deployment name"
defaultValue={settings?.AzureOpenAiModelPref}
required={true}
@ -51,15 +51,15 @@ export default function AzureAiOptions({ settings }) {
</div>
</div>
<div className="w-full flex items-center gap-4">
<div className="w-full flex items-center gap-[36px]">
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
Chat Model Token Limit
</label>
<select
name="AzureOpenAiTokenLimit"
defaultValue={settings?.AzureOpenAiTokenLimit || 4096}
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
required={true}
>
<option value={4096}>4,096 (gpt-3.5-turbo)</option>
@ -71,13 +71,13 @@ export default function AzureAiOptions({ settings }) {
</div>
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
Embedding Deployment Name
</label>
<input
type="text"
name="AzureOpenAiEmbeddingModelPref"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="Azure OpenAI embedding model deployment name"
defaultValue={settings?.AzureOpenAiEmbeddingModelPref}
required={true}

View File

@ -1,15 +1,15 @@
export default function CohereAiOptions({ settings }) {
return (
<div className="w-full flex flex-col">
<div className="w-full flex items-center gap-4">
<div className="w-full flex items-center gap-[36px] mt-1.5">
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
Cohere API Key
</label>
<input
type="password"
name="CohereApiKey"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="Cohere API Key"
defaultValue={settings?.CohereApiKey ? "*".repeat(20) : ""}
required={true}
@ -18,7 +18,7 @@ export default function CohereAiOptions({ settings }) {
/>
</div>
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
Chat Model Selection
</label>
<select

View File

@ -1,15 +1,15 @@
export default function GeminiLLMOptions({ settings }) {
return (
<div className="w-full flex flex-col">
<div className="w-full flex items-center gap-4">
<div className="w-full flex items-center gap-[36px] mt-1.5">
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
Google AI API Key
</label>
<input
type="password"
name="GeminiLLMApiKey"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="Google Gemini API Key"
defaultValue={settings?.GeminiLLMApiKey ? "*".repeat(20) : ""}
required={true}
@ -21,7 +21,7 @@ export default function GeminiLLMOptions({ settings }) {
{!settings?.credentialsOnly && (
<>
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
Chat Model Selection
</label>
<select
@ -45,7 +45,7 @@ export default function GeminiLLMOptions({ settings }) {
</select>
</div>
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
Safety Setting
</label>
<select

View File

@ -1,15 +1,15 @@
export default function GenericOpenAiOptions({ settings }) {
return (
<div className="flex flex-col gap-y-4">
<div className="flex gap-4 flex-wrap">
<div className="flex flex-col gap-y-7">
<div className="flex gap-[36px] mt-1.5 flex-wrap">
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
Base URL
</label>
<input
type="url"
name="GenericOpenAiBasePath"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="eg: https://proxy.openai.com"
defaultValue={settings?.GenericOpenAiBasePath}
required={true}
@ -18,13 +18,13 @@ export default function GenericOpenAiOptions({ settings }) {
/>
</div>
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
API Key
</label>
<input
type="password"
name="GenericOpenAiKey"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="Generic service API Key"
defaultValue={settings?.GenericOpenAiKey ? "*".repeat(20) : ""}
required={false}
@ -33,13 +33,13 @@ export default function GenericOpenAiOptions({ settings }) {
/>
</div>
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
Chat Model Name
</label>
<input
type="text"
name="GenericOpenAiModelPref"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="Model id used for chat requests"
defaultValue={settings?.GenericOpenAiModelPref}
required={true}
@ -47,15 +47,15 @@ export default function GenericOpenAiOptions({ settings }) {
/>
</div>
</div>
<div className="flex gap-x-4 flex-wrap">
<div className="flex gap-[36px] flex-wrap">
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
Token context window
</label>
<input
type="number"
name="GenericOpenAiTokenLimit"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="Content window limit (eg: 4096)"
min={1}
onScroll={(e) => e.target.blur()}
@ -65,13 +65,13 @@ export default function GenericOpenAiOptions({ settings }) {
/>
</div>
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
Max Tokens
</label>
<input
type="number"
name="GenericOpenAiMaxTokens"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="Max tokens per request (eg: 1024)"
min={1}
defaultValue={settings?.GenericOpenAiMaxTokens || 1024}

View File

@ -1,14 +1,14 @@
export default function GroqAiOptions({ settings }) {
return (
<div className="flex gap-x-4">
<div className="flex gap-[36px] mt-1.5">
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
Groq API Key
</label>
<input
type="password"
name="GroqApiKey"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="Groq API Key"
defaultValue={settings?.GroqApiKey ? "*".repeat(20) : ""}
required={true}
@ -19,7 +19,7 @@ export default function GroqAiOptions({ settings }) {
{!settings?.credentialsOnly && (
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
Chat Model Selection
</label>
<select

View File

@ -1,15 +1,15 @@
export default function HuggingFaceOptions({ settings }) {
return (
<div className="w-full flex flex-col">
<div className="w-full flex items-center gap-4">
<div className="w-full flex items-center gap-[36px] mt-1.5">
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
HuggingFace Inference Endpoint
</label>
<input
type="url"
name="HuggingFaceLLMEndpoint"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="https://example.endpoints.huggingface.cloud"
defaultValue={settings?.HuggingFaceLLMEndpoint}
required={true}
@ -18,13 +18,13 @@ export default function HuggingFaceOptions({ settings }) {
/>
</div>
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
HuggingFace Access Token
</label>
<input
type="password"
name="HuggingFaceLLMAccessToken"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="HuggingFace Access Token"
defaultValue={
settings?.HuggingFaceLLMAccessToken ? "*".repeat(20) : ""
@ -35,13 +35,13 @@ export default function HuggingFaceOptions({ settings }) {
/>
</div>
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
Model Token Limit
</label>
<input
type="number"
name="HuggingFaceLLMTokenLimit"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="4096"
min={1}
onScroll={(e) => e.target.blur()}

View File

@ -8,15 +8,15 @@ export default function KoboldCPPOptions({ settings }) {
const [basePath, setBasePath] = useState(settings?.KoboldCPPBasePath);
return (
<div className="flex gap-4 flex-wrap">
<div className="flex gap-[36px] mt-1.5 flex-wrap">
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
Base URL
</label>
<input
type="url"
name="KoboldCPPBasePath"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="http://127.0.0.1:5000/v1"
defaultValue={settings?.KoboldCPPBasePath}
required={true}
@ -28,13 +28,13 @@ export default function KoboldCPPOptions({ settings }) {
</div>
<KoboldCPPModelSelection settings={settings} basePath={basePath} />
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
Token context window
</label>
<input
type="number"
name="KoboldCPPTokenLimit"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="4096"
min={1}
onScroll={(e) => e.target.blur()}
@ -69,7 +69,7 @@ function KoboldCPPModelSelection({ settings, basePath = null }) {
if (loading || customModels.length === 0) {
return (
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
Chat Model Selection
</label>
<select
@ -89,7 +89,7 @@ function KoboldCPPModelSelection({ settings, basePath = null }) {
return (
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
Chat Model Selection
</label>
<select

View File

@ -29,7 +29,7 @@ export default function LMStudioOptions({ settings, showAlert = false }) {
};
return (
<div className="w-full flex flex-col">
<div className="w-full flex flex-col gap-y-7">
{showAlert && (
<div className="flex flex-col md:flex-row md:items-center gap-x-2 text-white mb-6 bg-blue-800/30 w-fit rounded-lg px-4 py-2">
<div className="gap-x-2 flex items-center">
@ -47,7 +47,7 @@ export default function LMStudioOptions({ settings, showAlert = false }) {
</a>
</div>
)}
<div className="w-full flex items-start gap-4">
<div className="w-full flex items-start gap-[36px] mt-1.5">
<LMStudioModelSelection settings={settings} basePath={basePath.value} />
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-2">
@ -56,7 +56,7 @@ export default function LMStudioOptions({ settings, showAlert = false }) {
<input
type="number"
name="LMStudioTokenLimit"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="4096"
defaultChecked="4096"
min={1}
@ -89,7 +89,7 @@ export default function LMStudioOptions({ settings, showAlert = false }) {
</div>
<div hidden={!showAdvancedControls}>
<div className="w-full flex items-start gap-4 mt-4">
<div className="w-full flex items-start gap-4">
<div className="flex flex-col w-60">
<div className="flex justify-between items-center mb-2">
<label className="text-white text-sm font-semibold">
@ -113,7 +113,7 @@ export default function LMStudioOptions({ settings, showAlert = false }) {
<input
type="url"
name="LMStudioBasePath"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="http://localhost:1234/v1"
value={basePathValue.value}
required={true}

View File

@ -8,16 +8,16 @@ export default function LiteLLMOptions({ settings }) {
const [apiKey, setApiKey] = useState(settings?.LiteLLMAPIKey);
return (
<div className="w-full flex flex-col gap-y-4">
<div className="w-full flex items-center gap-4">
<div className="w-full flex flex-col gap-y-7 mt-1.5">
<div className="w-full flex items-center gap-[36px]">
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
Base URL
</label>
<input
type="url"
name="LiteLLMBasePath"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="http://127.0.0.1:4000"
defaultValue={settings?.LiteLLMBasePath}
required={true}
@ -33,13 +33,13 @@ export default function LiteLLMOptions({ settings }) {
apiKey={apiKey}
/>
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
Token context window
</label>
<input
type="number"
name="LiteLLMTokenLimit"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="4096"
min={1}
onScroll={(e) => e.target.blur()}
@ -49,7 +49,7 @@ export default function LiteLLMOptions({ settings }) {
/>
</div>
</div>
<div className="w-full flex items-center gap-4">
<div className="w-full flex items-center gap-[36px]">
<div className="flex flex-col w-60">
<div className="flex flex-col gap-y-1 mb-4">
<label className="text-white text-sm font-semibold flex items-center gap-x-2">
@ -59,7 +59,7 @@ export default function LiteLLMOptions({ settings }) {
<input
type="password"
name="LiteLLMAPIKey"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="bg-zinc-900 text-white placeholder:text-white/20 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?.LiteLLMAPIKey ? "*".repeat(20) : ""}
autoComplete="off"
@ -99,7 +99,7 @@ function LiteLLMModelSelection({ settings, basePath = null, apiKey = null }) {
if (loading || customModels.length == 0) {
return (
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
Chat Model Selection
</label>
<select
@ -119,7 +119,7 @@ function LiteLLMModelSelection({ settings, basePath = null, apiKey = null }) {
return (
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
Chat Model Selection
</label>
<select

View File

@ -10,7 +10,7 @@ export default function LocalAiOptions({ settings, showAlert = false }) {
const [apiKey, setApiKey] = useState(settings?.LocalAiApiKey);
return (
<div className="w-full flex flex-col gap-y-4">
<div className="w-full flex flex-col gap-y-7">
{showAlert && (
<div className="flex flex-col md:flex-row md:items-center gap-x-2 text-white mb-6 bg-blue-800/30 w-fit rounded-lg px-4 py-2">
<div className="gap-x-2 flex items-center">
@ -28,15 +28,15 @@ export default function LocalAiOptions({ settings, showAlert = false }) {
</a>
</div>
)}
<div className="w-full flex items-center gap-4">
<div className="w-full flex items-center gap-[36px] mt-1.5">
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
Local AI Base URL
</label>
<input
type="url"
name="LocalAiBasePath"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="http://localhost:1234/v1"
defaultValue={settings?.LocalAiBasePath}
required={true}
@ -54,13 +54,13 @@ export default function LocalAiOptions({ settings, showAlert = false }) {
apiKey={apiKey}
/>
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
Token context window
</label>
<input
type="number"
name="LocalAiTokenLimit"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="4096"
min={1}
onScroll={(e) => e.target.blur()}
@ -84,7 +84,7 @@ export default function LocalAiOptions({ settings, showAlert = false }) {
<input
type="password"
name="LocalAiApiKey"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="bg-zinc-900 text-white placeholder:text-white/20 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"
@ -124,7 +124,7 @@ function LocalAIModelSelection({ settings, basePath = null, apiKey = null }) {
if (loading || customModels.length == 0) {
return (
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
Chat Model Selection
</label>
<select
@ -144,7 +144,7 @@ function LocalAIModelSelection({ settings, basePath = null, apiKey = null }) {
return (
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
Chat Model Selection
</label>
<select

View File

@ -6,15 +6,15 @@ export default function MistralOptions({ settings }) {
const [mistralKey, setMistralKey] = useState(settings?.MistralApiKey);
return (
<div className="flex gap-x-4">
<div className="flex gap-[36px] mt-1.5">
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
Mistral API Key
</label>
<input
type="password"
name="MistralApiKey"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="Mistral API Key"
defaultValue={settings?.MistralApiKey ? "*".repeat(20) : ""}
required={true}
@ -56,7 +56,7 @@ function MistralModelSelection({ apiKey, settings }) {
if (loading || customModels.length == 0) {
return (
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
Chat Model Selection
</label>
<select
@ -76,7 +76,7 @@ function MistralModelSelection({ apiKey, settings }) {
return (
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
Chat Model Selection
</label>
<select

View File

@ -13,7 +13,7 @@ export default function NativeLLMOptions({ settings }) {
</p>
</div>
</div>
<div className="w-full flex items-center gap-4">
<div className="w-full flex items-center gap-[36px]">
<NativeModelSelection settings={settings} />
</div>
</div>
@ -37,7 +37,7 @@ function NativeModelSelection({ settings }) {
if (loading || customModels.length == 0) {
return (
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
Model Selection
</label>
<select
@ -56,7 +56,7 @@ function NativeModelSelection({ settings }) {
return (
<>
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
Model Selection
</label>
<select
@ -82,13 +82,13 @@ function NativeModelSelection({ settings }) {
</select>
</div>
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
Token context window
</label>
<input
type="number"
name="NativeLLMTokenLimit"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="4096"
min={1}
onScroll={(e) => e.target.blur()}

View File

@ -28,8 +28,8 @@ export default function OllamaLLMOptions({ settings }) {
};
return (
<div className="w-full flex flex-col gap-y-4">
<div className="w-full flex items-start gap-4">
<div className="w-full flex flex-col gap-y-7">
<div className="w-full flex items-start gap-[36px] mt-1.5">
<OllamaLLMModelSelection
settings={settings}
basePath={basePath.value}
@ -41,7 +41,7 @@ export default function OllamaLLMOptions({ settings }) {
<input
type="number"
name="OllamaLLMTokenLimit"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="4096"
defaultChecked="4096"
min={1}
@ -98,7 +98,7 @@ export default function OllamaLLMOptions({ settings }) {
<input
type="url"
name="OllamaLLMBasePath"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="http://127.0.0.1:11434"
value={basePathValue.value}
required={true}

View File

@ -6,15 +6,15 @@ export default function OpenAiOptions({ settings }) {
const [openAIKey, setOpenAIKey] = useState(settings?.OpenAiKey);
return (
<div className="flex gap-x-4">
<div className="flex gap-[36px] mt-1.5">
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
API Key
</label>
<input
type="password"
name="OpenAiKey"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="OpenAI API Key"
defaultValue={settings?.OpenAiKey ? "*".repeat(20) : ""}
required={true}
@ -60,7 +60,7 @@ function OpenAIModelSelection({ apiKey, settings }) {
if (loading) {
return (
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
Chat Model Selection
</label>
<select
@ -78,7 +78,7 @@ function OpenAIModelSelection({ apiKey, settings }) {
return (
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
Chat Model Selection
</label>
<select

View File

@ -3,15 +3,15 @@ import { useState, useEffect } from "react";
export default function OpenRouterOptions({ settings }) {
return (
<div className="flex gap-x-4">
<div className="flex gap-[36px] mt-1.5">
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
OpenRouter API Key
</label>
<input
type="password"
name="OpenRouterApiKey"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="OpenRouter API Key"
defaultValue={settings?.OpenRouterApiKey ? "*".repeat(20) : ""}
required={true}
@ -52,7 +52,7 @@ function OpenRouterModelSelection({ settings }) {
if (loading || Object.keys(groupedModels).length === 0) {
return (
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
Chat Model Selection
</label>
<select
@ -70,7 +70,7 @@ function OpenRouterModelSelection({ settings }) {
return (
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
Chat Model Selection
</label>
<select

View File

@ -3,15 +3,15 @@ import { useState, useEffect } from "react";
export default function PerplexityOptions({ settings }) {
return (
<div className="flex gap-x-4">
<div className="flex gap-[36px] mt-1.5">
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
Perplexity API Key
</label>
<input
type="password"
name="PerplexityApiKey"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="Perplexity API Key"
defaultValue={settings?.PerplexityApiKey ? "*".repeat(20) : ""}
required={true}
@ -43,7 +43,7 @@ function PerplexityModelSelection({ settings }) {
if (loading || customModels.length == 0) {
return (
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
Chat Model Selection
</label>
<select
@ -61,7 +61,7 @@ function PerplexityModelSelection({ settings }) {
return (
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
Chat Model Selection
</label>
<select

View File

@ -1,14 +1,14 @@
export default function TextGenWebUIOptions({ settings }) {
return (
<div className="flex gap-4 flex-wrap">
<div className="flex gap-[36px] mt-1.5 flex-wrap">
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
Base URL
</label>
<input
type="url"
name="TextGenWebUIBasePath"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="http://127.0.0.1:5000/v1"
defaultValue={settings?.TextGenWebUIBasePath}
required={true}
@ -17,13 +17,13 @@ export default function TextGenWebUIOptions({ settings }) {
/>
</div>
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
Token context window
</label>
<input
type="number"
name="TextGenWebUITokenLimit"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="Content window limit (eg: 4096)"
min={1}
onScroll={(e) => e.target.blur()}
@ -33,13 +33,13 @@ export default function TextGenWebUIOptions({ settings }) {
/>
</div>
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
API Key (Optional)
</label>
<input
type="password"
name="TextGenWebUIAPIKey"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="TextGen Web UI API Key"
defaultValue={settings?.TextGenWebUIAPIKey ? "*".repeat(20) : ""}
autoComplete="off"

View File

@ -3,15 +3,15 @@ import { useState, useEffect } from "react";
export default function TogetherAiOptions({ settings }) {
return (
<div className="flex gap-x-4">
<div className="flex gap-[36px] mt-1.5">
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
Together AI API Key
</label>
<input
type="password"
name="TogetherAiApiKey"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="Together AI API Key"
defaultValue={settings?.TogetherAiApiKey ? "*".repeat(20) : ""}
required={true}
@ -52,7 +52,7 @@ function TogetherAiModelSelection({ settings }) {
if (loading || Object.keys(groupedModels).length === 0) {
return (
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
Chat Model Selection
</label>
<select
@ -70,7 +70,7 @@ function TogetherAiModelSelection({ settings }) {
return (
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
Chat Model Selection
</label>
<select

View File

@ -68,7 +68,7 @@ export default function RecoveryCodeModal({
<div className="flex w-full justify-center items-center p-3 space-x-2 rounded-b border-gray-500/50 -mt-4 mb-4">
<button
type="button"
className="transition-all duration-300 text-xs md:w-[500px] md:h-[34px] h-[48px] w-full m-2 font-semibold rounded-lg bg-primary-button hover:bg-secondary border-2 border-transparent hover:border-[#46C8FF] hover:text-white whitespace-nowrap shadow-[0_4px_14px_rgba(0,0,0,0.25)] flex justify-center items-center gap-x-2"
className="transition-all duration-300 text-xs md:w-[500px] md:h-[34px] h-[48px] w-full m-2 font-semibold rounded-lg bg-primary-button hover:bg-secondary border-2 border-transparent hover:border-primary-button hover:text-white whitespace-nowrap shadow-[0_4px_14px_rgba(0,0,0,0.25)] flex justify-center items-center gap-x-2"
onClick={downloadClicked ? handleClose : downloadRecoveryCodes}
>
{downloadClicked ? (

View File

@ -65,7 +65,7 @@ export default function ConfluenceOptions() {
<input
type="url"
name="pageUrl"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="https://example.atlassian.net/wiki/spaces/~7120208c08555d52224113949698b933a3bb56/pages/851969/Test+anythingLLM+page"
required={true}
autoComplete="off"
@ -84,7 +84,7 @@ export default function ConfluenceOptions() {
<input
type="email"
name="username"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="jdoe@example.com"
required={true}
autoComplete="off"
@ -132,7 +132,7 @@ export default function ConfluenceOptions() {
<input
type="password"
name="accessToken"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="abcd1234"
required={true}
autoComplete="off"

View File

@ -77,7 +77,7 @@ export default function GithubOptions() {
<input
type="url"
name="repo"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="https://github.com/Mintplex-Labs/anything-llm"
required={true}
autoComplete="off"
@ -102,7 +102,7 @@ export default function GithubOptions() {
<input
type="text"
name="accessToken"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="github_pat_1234_abcdefg"
required={false}
autoComplete="off"
@ -135,7 +135,7 @@ export default function GithubOptions() {
classNames={{
tag: "bg-blue-300/10 text-zinc-800",
input:
"flex bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white",
"flex bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none",
}}
/>
</div>

View File

@ -64,7 +64,7 @@ export default function WebsiteDepthOptions() {
<input
type="url"
name="url"
className="border-none bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="border-none bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="https://example.com"
required={true}
autoComplete="off"
@ -84,7 +84,7 @@ export default function WebsiteDepthOptions() {
name="depth"
min="1"
max="5"
className="border-none bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="border-none bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
required={true}
defaultValue="1"
/>
@ -102,7 +102,7 @@ export default function WebsiteDepthOptions() {
type="number"
name="maxLinks"
min="1"
className="border-none bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="border-none bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
required={true}
defaultValue="20"
/>

View File

@ -59,7 +59,7 @@ export default function YoutubeOptions() {
<input
type="url"
name="url"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="https://youtube.com/watch?v=abc123"
required={true}
autoComplete="off"

View File

@ -56,7 +56,7 @@ export default function DataConnectors() {
<input
type="text"
placeholder="Search data connectors"
className="border-none bg-zinc-600 z-20 pl-10 h-[38px] rounded-full w-full px-4 py-1 text-sm border-2 border-slate-300/40 outline-none focus:border-white text-white"
className="border-none bg-zinc-600 z-20 pl-10 h-[38px] rounded-full w-full px-4 py-1 text-sm border-2 border-slate-300/40 outline-none focus:outline-primary-button active:outline-primary-button outline-none text-white"
autoComplete="off"
value={searchQuery}
onChange={(e) => setSearchQuery(e.target.value)}

View File

@ -52,7 +52,7 @@ export default function NewWorkspaceModal({ hideModal = noop }) {
name="name"
type="text"
id="name"
className="bg-zinc-900 w-full text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="bg-zinc-900 w-full text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="My Workspace"
required={true}
autoComplete="off"

View File

@ -82,7 +82,7 @@ const RecoveryForm = ({ onSubmit, setShowRecoveryForm }) => {
<div className="flex items-center md:p-12 md:px-0 px-6 mt-12 md:mt-0 space-x-2 border-gray-600 w-full flex-col gap-y-8">
<button
type="submit"
className="md:text-primary-button md:bg-transparent md:w-[300px] text-dark-text text-sm font-bold focus:ring-4 focus:outline-none rounded-md border-[1.5px] border-[#46C8FF] md:h-[34px] h-[48px] md:hover:text-white md:hover:bg-primary-button bg-primary-button focus:z-10 w-full"
className="md:text-primary-button md:bg-transparent md:w-[300px] text-dark-text text-sm font-bold focus:ring-4 focus:outline-none rounded-md border-[1.5px] border-primary-button md:h-[34px] h-[48px] md:hover:text-white md:hover:bg-primary-button bg-primary-button focus:z-10 w-full"
>
Reset Password
</button>
@ -151,7 +151,7 @@ const ResetPasswordForm = ({ onSubmit }) => {
<div className="flex items-center md:p-12 md:px-0 px-6 mt-12 md:mt-0 space-x-2 border-gray-600 w-full flex-col gap-y-8">
<button
type="submit"
className="md:text-primary-button md:bg-transparent md:w-[300px] text-dark-text text-sm font-bold focus:ring-4 focus:outline-none rounded-md border-[1.5px] border-[#46C8FF] md:h-[34px] h-[48px] md:hover:text-white md:hover:bg-primary-button bg-primary-button focus:z-10 w-full"
className="md:text-primary-button md:bg-transparent md:w-[300px] text-dark-text text-sm font-bold focus:ring-4 focus:outline-none rounded-md border-[1.5px] border-primary-button md:h-[34px] h-[48px] md:hover:text-white md:hover:bg-primary-button bg-primary-button focus:z-10 w-full"
>
Reset Password
</button>
@ -322,7 +322,7 @@ export default function MultiUserAuth() {
<button
disabled={loading}
type="submit"
className="md:text-primary-button md:bg-transparent text-dark-text text-sm font-bold focus:ring-4 focus:outline-none rounded-md border-[1.5px] border-[#46C8FF] md:h-[34px] h-[48px] md:hover:text-white md:hover:bg-primary-button bg-primary-button focus:z-10 w-full"
className="md:text-primary-button md:bg-transparent text-dark-text text-sm font-bold focus:ring-4 focus:outline-none rounded-md border-[1.5px] border-primary-button md:h-[34px] h-[48px] md:hover:text-white md:hover:bg-primary-button bg-primary-button focus:z-10 w-full"
>
{loading
? t("login.multi-user.validating")

View File

@ -107,7 +107,7 @@ export default function SingleUserAuth() {
<button
disabled={loading}
type="submit"
className="md:text-primary-button md:bg-transparent text-dark-text text-sm font-bold focus:ring-4 focus:outline-none rounded-md border-[1.5px] border-[#46C8FF] md:h-[34px] h-[48px] md:hover:text-white md:hover:bg-primary-button bg-primary-button focus:z-10 w-full"
className="md:text-primary-button md:bg-transparent text-dark-text text-sm font-bold focus:ring-4 focus:outline-none rounded-md border-[1.5px] border-primary-button md:h-[34px] h-[48px] md:hover:text-white md:hover:bg-primary-button bg-primary-button focus:z-10 w-full"
>
{loading ? "Validating..." : "Login"}
</button>

View File

@ -1,6 +1,6 @@
import React, { useEffect, useState } from "react";
import { CaretRight } from "@phosphor-icons/react";
import { Link } from "react-router-dom";
import { Link, useLocation } from "react-router-dom";
export default function MenuOption({
btnText,
@ -14,14 +14,14 @@ export default function MenuOption({
isChild = false,
}) {
const storageKey = generateStorageKey({ key: btnText });
const location = window.location.pathname;
const location = useLocation();
const hasChildren = childOptions.length > 0;
const hasVisibleChildren = hasVisibleOptions(user, childOptions);
const { isExpanded, setIsExpanded } = useIsExpanded({
storageKey,
hasVisibleChildren,
childOptions,
location,
location: location.pathname,
});
if (hidden) return null;
@ -43,9 +43,10 @@ export default function MenuOption({
}
const isActive = hasChildren
? (!isExpanded && childOptions.some((child) => child.href === location)) ||
location === href
: location === href;
? (!isExpanded &&
childOptions.some((child) => child.href === location.pathname)) ||
location.pathname === href
: location.pathname === href;
const handleClick = (e) => {
if (hasChildren) {

View File

@ -8,13 +8,13 @@ export default function ElevenLabsOptions({ settings }) {
return (
<div className="flex gap-x-4">
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
API Key
</label>
<input
type="password"
name="TTSElevenLabsKey"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="ElevenLabs API Key"
defaultValue={settings?.TTSElevenLabsKey ? "*".repeat(20) : ""}
required={true}
@ -60,7 +60,7 @@ function ElevenLabsModelSelection({ apiKey, settings }) {
if (loading) {
return (
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
Chat Model Selection
</label>
<select
@ -78,7 +78,7 @@ function ElevenLabsModelSelection({ apiKey, settings }) {
return (
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
Chat Model Selection
</label>
<select

View File

@ -10,13 +10,13 @@ export default function OpenAiTextToSpeechOptions({ settings }) {
return (
<div className="flex gap-x-4">
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
API Key
</label>
<input
type="password"
name="TTSOpenAIKey"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="OpenAI API Key"
defaultValue={apiKey ? "*".repeat(20) : ""}
required={true}
@ -25,7 +25,7 @@ export default function OpenAiTextToSpeechOptions({ settings }) {
/>
</div>
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
Voice Model
</label>
<select

View File

@ -11,7 +11,7 @@ export default function NativeTranscriptionOptions({ settings }) {
<LocalWarning model={model} />
<div className="w-full flex items-center gap-4">
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
{t("common.selection")}
</label>
<select

View File

@ -5,15 +5,15 @@ export default function OpenAiWhisperOptions({ settings }) {
const [_openAIKey, setOpenAIKey] = useState(settings?.OpenAiKey);
return (
<div className="flex gap-x-4">
<div className="flex gap-x-7 gap-[36px] mt-1.5">
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
API Key
</label>
<input
type="password"
name="OpenAiKey"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="OpenAI API Key"
defaultValue={settings?.OpenAiKey ? "*".repeat(20) : ""}
required={true}
@ -24,7 +24,7 @@ export default function OpenAiWhisperOptions({ settings }) {
/>
</div>
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
Whisper Model
</label>
<select

View File

@ -1,15 +1,15 @@
export default function AstraDBOptions({ settings }) {
return (
<div className="w-full flex flex-col gap-y-4">
<div className="w-full flex items-center gap-4">
<div className="w-full flex flex-col gap-y-7">
<div className="w-full flex items-center gap-[36px] mt-1.5">
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
Astra DB Endpoint
</label>
<input
type="url"
name="AstraDBEndpoint"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="Astra DB API endpoint"
defaultValue={settings?.AstraDBEndpoint}
required={true}
@ -19,13 +19,13 @@ export default function AstraDBOptions({ settings }) {
</div>
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
Astra DB Application Token
</label>
<input
type="password"
name="AstraDBApplicationToken"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="AstraCS:..."
defaultValue={
settings?.AstraDBApplicationToken ? "*".repeat(20) : ""

View File

@ -1,15 +1,15 @@
export default function ChromaDBOptions({ settings }) {
return (
<div className="w-full flex flex-col gap-y-4">
<div className="w-full flex items-center gap-4">
<div className="w-full flex flex-col gap-y-7">
<div className="w-full flex items-center gap-[36px] mt-1.5">
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
Chroma Endpoint
</label>
<input
type="url"
name="ChromaEndpoint"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="http://localhost:8000"
defaultValue={settings?.ChromaEndpoint}
required={true}
@ -19,7 +19,7 @@ export default function ChromaDBOptions({ settings }) {
</div>
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
API Header
</label>
<input
@ -27,13 +27,13 @@ export default function ChromaDBOptions({ settings }) {
autoComplete="off"
type="text"
defaultValue={settings?.ChromaApiHeader}
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="X-Api-Key"
/>
</div>
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
API Key
</label>
<input
@ -41,7 +41,7 @@ export default function ChromaDBOptions({ settings }) {
autoComplete="off"
type="password"
defaultValue={settings?.ChromaApiKey ? "*".repeat(20) : ""}
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="sk-myApiKeyToAccessMyChromaInstance"
/>
</div>

View File

@ -1,15 +1,15 @@
export default function MilvusDBOptions({ settings }) {
return (
<div className="w-full flex flex-col gap-y-4">
<div className="w-full flex items-center gap-4">
<div className="w-full flex flex-col gap-y-7">
<div className="w-full flex items-center gap-[36px] mt-1.5">
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
Milvus DB Address
</label>
<input
type="text"
name="MilvusAddress"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="http://localhost:19530"
defaultValue={settings?.MilvusAddress}
required={true}
@ -19,13 +19,13 @@ export default function MilvusDBOptions({ settings }) {
</div>
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
Milvus Username
</label>
<input
type="text"
name="MilvusUsername"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="username"
defaultValue={settings?.MilvusUsername}
autoComplete="off"
@ -33,13 +33,13 @@ export default function MilvusDBOptions({ settings }) {
/>
</div>
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
Milvus Password
</label>
<input
type="password"
name="MilvusPassword"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="password"
defaultValue={settings?.MilvusPassword ? "*".repeat(20) : ""}
autoComplete="off"

View File

@ -1,15 +1,15 @@
export default function PineconeDBOptions({ settings }) {
return (
<div className="w-full flex flex-col gap-y-4">
<div className="w-full flex items-center gap-4">
<div className="w-full flex flex-col gap-y-7">
<div className="w-full flex items-center gap-[36px] mt-1.5">
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
Pinecone DB API Key
</label>
<input
type="password"
name="PineConeKey"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="Pinecone API Key"
defaultValue={settings?.PineConeKey ? "*".repeat(20) : ""}
required={true}
@ -18,13 +18,13 @@ export default function PineconeDBOptions({ settings }) {
/>
</div>
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
Pinecone Index Name
</label>
<input
type="text"
name="PineConeIndex"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="my-index"
defaultValue={settings?.PineConeIndex}
required={true}

View File

@ -1,15 +1,15 @@
export default function QDrantDBOptions({ settings }) {
return (
<div className="w-full flex flex-col gap-y-4">
<div className="w-full flex items-center gap-4">
<div className="w-full flex flex-col gap-y-7">
<div className="w-full flex items-center gap-[36px] mt-1.5">
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
QDrant API Endpoint
</label>
<input
type="url"
name="QdrantEndpoint"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="http://localhost:6633"
defaultValue={settings?.QdrantEndpoint}
required={true}
@ -19,13 +19,13 @@ export default function QDrantDBOptions({ settings }) {
</div>
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
API Key
</label>
<input
type="password"
name="QdrantApiKey"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="wOeqxsYP4....1244sba"
defaultValue={settings?.QdrantApiKey}
autoComplete="off"

View File

@ -1,15 +1,15 @@
export default function WeaviateDBOptions({ settings }) {
return (
<div className="w-full flex flex-col gap-y-4">
<div className="w-full flex items-center gap-4">
<div className="w-full flex flex-col gap-y-7">
<div className="w-full flex items-center gap-[36px] mt-1.5">
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
Weaviate Endpoint
</label>
<input
type="url"
name="WeaviateEndpoint"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="http://localhost:8080"
defaultValue={settings?.WeaviateEndpoint}
required={true}
@ -19,13 +19,13 @@ export default function WeaviateDBOptions({ settings }) {
</div>
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
API Key
</label>
<input
type="password"
name="WeaviateApiKey"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="sk-123Abcweaviate"
defaultValue={settings?.WeaviateApiKey}
autoComplete="off"

View File

@ -1,15 +1,15 @@
export default function ZillizCloudOptions({ settings }) {
return (
<div className="w-full flex flex-col gap-y-4">
<div className="w-full flex items-center gap-4">
<div className="w-full flex items-center gap-[36px] mt-1.5">
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
Cluster Endpoint
</label>
<input
type="text"
name="ZillizEndpoint"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="https://sample.api.gcp-us-west1.zillizcloud.com"
defaultValue={settings?.ZillizEndpoint}
required={true}
@ -19,13 +19,13 @@ export default function ZillizCloudOptions({ settings }) {
</div>
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
API Token
</label>
<input
type="password"
name="ZillizApiToken"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="Zilliz cluster API Token"
defaultValue={settings?.ZillizApiToken ? "*".repeat(20) : ""}
autoComplete="off"

View File

@ -57,7 +57,7 @@ export default function Citations({ sources = [] }) {
/>
</button>
{open && (
<div className="flex flex-wrap md:flex-row flex-col md:items-center gap-4 overflow-x-scroll mt-1 doc__source">
<div className="flex flex-wrap md:flex-row md:items-center gap-4 overflow-x-scroll mt-1 doc__source ml-14">
{combineLikeSources(sources).map((source) => (
<Citation
key={v4()}

View File

@ -33,7 +33,7 @@ function ActionMenu({ chatId, forkThread, isEditing, role }) {
};
}, []);
if (isEditing || role === "user") return null;
if (!chatId || isEditing || role === "user") return null;
return (
<div className="mt-2 -ml-0.5 relative" ref={menuRef}>

View File

@ -16,7 +16,7 @@ export default function TTSMessage({ slug, chatId, message }) {
getSettings();
}, []);
if (loading) return null;
if (!chatId || loading) return null;
if (provider !== "native")
return <AsyncTTSMessage slug={slug} chatId={chatId} />;
return <NativeTTSMessage message={message} />;

View File

@ -24,14 +24,14 @@ export default function StopGenerationButton() {
xmlns="http://www.w3.org/2000/svg"
>
<circle
className="group-hover:stroke-[#46C8FF] stroke-white"
className="group-hover:stroke-primary-button stroke-white"
cx="10"
cy="10.562"
r="9"
strokeWidth="2"
/>
<rect
className="group-hover:fill-[#46C8FF] fill-white"
className="group-hover:fill-primary-button fill-white"
x="6.3999"
y="6.96204"
width="7.2"

View File

@ -134,13 +134,13 @@ export default function NewSQLConnection({ isOpen, closeModal, onSubmit }) {
</div>
<div className="flex flex-col w-full">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
Connection name
</label>
<input
type="text"
name="name"
className="border-none bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="border-none bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="a unique name to identify this SQL connection"
required={true}
autoComplete="off"
@ -150,13 +150,13 @@ export default function NewSQLConnection({ isOpen, closeModal, onSubmit }) {
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2">
<div className="flex flex-col">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
Database user
</label>
<input
type="text"
name="username"
className="border-none bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="border-none bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="root"
required={true}
autoComplete="off"
@ -164,13 +164,13 @@ export default function NewSQLConnection({ isOpen, closeModal, onSubmit }) {
/>
</div>
<div className="flex flex-col">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
Database user password
</label>
<input
type="text"
name="password"
className="border-none bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="border-none bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="password123"
required={true}
autoComplete="off"
@ -181,13 +181,13 @@ export default function NewSQLConnection({ isOpen, closeModal, onSubmit }) {
<div className="grid grid-cols-1 gap-4 sm:grid-cols-3">
<div className="sm:col-span-2">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
Server endpoint
</label>
<input
type="text"
name="host"
className="border-none bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="border-none bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="the hostname or endpoint for your database"
required={true}
autoComplete="off"
@ -195,13 +195,13 @@ export default function NewSQLConnection({ isOpen, closeModal, onSubmit }) {
/>
</div>
<div>
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
Port
</label>
<input
type="text"
name="port"
className="border-none bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="border-none bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="3306"
required={false}
autoComplete="off"
@ -211,13 +211,13 @@ export default function NewSQLConnection({ isOpen, closeModal, onSubmit }) {
</div>
<div className="flex flex-col">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
Database
</label>
<input
type="text"
name="database"
className="border-none bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="border-none bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="the database the agent will interact with"
required={true}
autoComplete="off"
@ -239,7 +239,7 @@ export default function NewSQLConnection({ isOpen, closeModal, onSubmit }) {
<button
type="submit"
form="sql-connection-form"
className="border-none text-xs px-2 py-1 font-semibold rounded-lg bg-primary-button hover:bg-secondary border-2 border-transparent hover:border-[#46C8FF] hover:text-white h-[32px] w-fit -mr-8 whitespace-nowrap shadow-[0_4px_14px_rgba(0,0,0,0.25)]"
className="border-none text-xs px-2 py-1 font-semibold rounded-lg bg-primary-button hover:bg-secondary border-2 border-transparent hover:border-primary-button hover:text-white h-[32px] w-fit -mr-8 whitespace-nowrap shadow-[0_4px_14px_rgba(0,0,0,0.25)]"
>
Save connection
</button>

View File

@ -14,13 +14,13 @@ export function GoogleSearchOptions({ settings }) {
</p>
<div className="flex gap-x-4">
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
Search engine ID
</label>
<input
type="text"
name="env::AgentGoogleSearchEngineId"
className="border-none bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="border-none bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="Google Search Engine Id"
defaultValue={settings?.AgentGoogleSearchEngineId}
required={true}
@ -29,13 +29,13 @@ export function GoogleSearchOptions({ settings }) {
/>
</div>
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
Programmatic Access API Key
</label>
<input
type="password"
name="env::AgentGoogleSearchEngineKey"
className="border-none bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="border-none bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="Google Search Engine API Key"
defaultValue={
settings?.AgentGoogleSearchEngineKey ? "*".repeat(20) : ""
@ -66,13 +66,13 @@ export function SerperDotDevOptions({ settings }) {
</p>
<div className="flex gap-x-4">
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
API Key
</label>
<input
type="password"
name="env::AgentSerperApiKey"
className="border-none bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="border-none bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="Serper.dev API Key"
defaultValue={settings?.AgentSerperApiKey ? "*".repeat(20) : ""}
required={true}
@ -101,13 +101,13 @@ export function BingSearchOptions({ settings }) {
</p>
<div className="flex gap-x-4">
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
API Key
</label>
<input
type="password"
name="env::AgentBingSearchApiKey"
className="border-none bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="border-none bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="Bing Web Search API Key"
defaultValue={settings?.AgentBingSearchApiKey ? "*".repeat(20) : ""}
required={true}
@ -164,13 +164,13 @@ export function SerplySearchOptions({ settings }) {
</p>
<div className="flex gap-x-4">
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
API Key
</label>
<input
type="password"
name="env::AgentSerplyApiKey"
className="border-none bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="border-none bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="Serply API Key"
defaultValue={settings?.AgentSerplyApiKey ? "*".repeat(20) : ""}
required={true}
@ -187,13 +187,13 @@ export function SearXNGOptions({ settings }) {
return (
<div className="flex gap-x-4">
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
<label className="text-white text-sm font-semibold block mb-3">
SearXNG API base URL
</label>
<input
type="url"
name="env::AgentSearXNGApiUrl"
className="border-none bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="border-none bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="SearXNG API Key"
defaultValue={settings?.AgentSearXNGApiUrl}
required={true}

View File

@ -159,7 +159,7 @@ export default function AgentWebSearchSelection({
/>
)}
{searchMenuOpen ? (
<div className="absolute top-0 left-0 w-full max-w-[640px] max-h-[310px] overflow-auto white-scrollbar min-h-[64px] bg-dark-input rounded-lg flex flex-col justify-between cursor-pointer border-2 border-[#46C8FF] z-20">
<div className="absolute top-0 left-0 w-full max-w-[640px] max-h-[310px] overflow-auto white-scrollbar min-h-[64px] bg-dark-input rounded-lg flex flex-col justify-between cursor-pointer border-2 border-primary-button z-20">
<div className="w-full flex flex-col gap-y-1">
<div className="flex items-center sticky top-0 border-b border-[#9CA3AF] mx-4 bg-dark-input">
<MagnifyingGlass
@ -172,7 +172,7 @@ export default function AgentWebSearchSelection({
name="web-provider-search"
autoComplete="off"
placeholder="Search available web-search providers"
className="border-none -ml-4 my-2 bg-transparent z-20 pl-12 h-[38px] w-full px-4 py-1 text-sm outline-none focus:border-white text-white placeholder:text-white placeholder:font-medium"
className="border-none -ml-4 my-2 bg-transparent z-20 pl-12 h-[38px] w-full px-4 py-1 text-sm outline-none text-white placeholder:text-white placeholder:font-medium"
onChange={(e) => setSearchQuery(e.target.value)}
ref={searchInputRef}
onKeyDown={(e) => {
@ -202,7 +202,7 @@ export default function AgentWebSearchSelection({
</div>
) : (
<button
className="w-full max-w-[640px] h-[64px] bg-dark-input rounded-lg flex items-center p-[14px] justify-between cursor-pointer border-2 border-transparent hover:border-[#46C8FF] transition-all duration-300"
className="w-full max-w-[640px] h-[64px] bg-dark-input rounded-lg flex items-center p-[14px] justify-between cursor-pointer border-2 border-transparent hover:border-primary-button transition-all duration-300"
type="button"
onClick={() => setSearchMenuOpen(true)}
>

View File

@ -65,7 +65,7 @@ export default function ApiKeyRow({ apiKey }) {
</button>
<button
onClick={handleDelete}
className="font-medium text-red-300 px-2 py-1 rounded-lg hover:bg-red-800 hover:bg-opacity-20"
className="font-medium px-2 py-1 rounded-lg hover:bg-sidebar-gradient text-white hover:text-white/80 hover:bg-opacity-20"
>
<Trash className="h-5 w-5" />
</button>

View File

@ -56,7 +56,7 @@ export default function NewIconForm({ icon, url, onSave, onRemove }) {
<form onSubmit={handleSubmit} className="flex items-center gap-x-1.5">
<div className="relative" ref={dropdownRef}>
<div
className="h-[34px] w-[34px] bg-dark-highlight rounded-full flex items-center justify-center cursor-pointer"
className="h-[34px] w-[34px] bg-dark-highlight rounded-full flex items-center justify-center cursor-pointer hover:outline-primary-button hover:outline"
onClick={() => setIsDropdownOpen(!isDropdownOpen)}
>
{React.createElement(ICON_COMPONENTS[selectedIcon] || Plus, {
@ -87,7 +87,7 @@ export default function NewIconForm({ icon, url, onSave, onRemove }) {
value={selectedUrl}
onChange={handleUrlChange}
placeholder="https://example.com"
className="bg-zinc-900 text-white placeholder-white/20 text-sm rounded-md p-2.5 w-[300px] h-[32px]"
className="bg-zinc-900 text-white placeholder-white/20 text-sm rounded-md p-2.5 w-[300px] h-[32px] focus:outline-primary-button active:outline-primary-button outline-none"
required
/>
{selectedIcon !== "Plus" && (

View File

@ -109,7 +109,7 @@ export default function SpeechToTextProvider({ settings }) {
/>
)}
{searchMenuOpen ? (
<div className="absolute top-0 left-0 w-full max-w-[640px] max-h-[310px] overflow-auto white-scrollbar min-h-[64px] bg-dark-input rounded-lg flex flex-col justify-between cursor-pointer border-2 border-[#46C8FF] z-20">
<div className="absolute top-0 left-0 w-full max-w-[640px] max-h-[310px] overflow-auto white-scrollbar min-h-[64px] bg-dark-input rounded-lg flex flex-col justify-between cursor-pointer border-2 border-primary-button z-20">
<div className="w-full flex flex-col gap-y-1">
<div className="flex items-center sticky top-0 border-b border-[#9CA3AF] mx-4 bg-dark-input">
<MagnifyingGlass
@ -122,7 +122,7 @@ export default function SpeechToTextProvider({ settings }) {
name="stt-provider-search"
autoComplete="off"
placeholder="Search speech to text providers"
className="-ml-4 my-2 bg-transparent z-20 pl-12 h-[38px] w-full px-4 py-1 text-sm outline-none focus:border-white text-white placeholder:text-white placeholder:font-medium"
className="-ml-4 my-2 bg-transparent z-20 pl-12 h-[38px] w-full px-4 py-1 text-sm outline-none text-white placeholder:text-white placeholder:font-medium"
onChange={(e) => setSearchQuery(e.target.value)}
ref={searchInputRef}
onKeyDown={(e) => {
@ -153,7 +153,7 @@ export default function SpeechToTextProvider({ settings }) {
</div>
) : (
<button
className="w-full max-w-[640px] h-[64px] bg-dark-input rounded-lg flex items-center p-[14px] justify-between cursor-pointer border-2 border-transparent hover:border-[#46C8FF] transition-all duration-300"
className="w-full max-w-[640px] h-[64px] bg-dark-input rounded-lg flex items-center p-[14px] justify-between cursor-pointer border-2 border-transparent hover:border-primary-button transition-all duration-300"
type="button"
onClick={() => setSearchMenuOpen(true)}
>

View File

@ -124,7 +124,7 @@ export default function TextToSpeechProvider({ settings }) {
/>
)}
{searchMenuOpen ? (
<div className="absolute top-0 left-0 w-full max-w-[640px] max-h-[310px] overflow-auto white-scrollbar min-h-[64px] bg-dark-input rounded-lg flex flex-col justify-between cursor-pointer border-2 border-[#46C8FF] z-20">
<div className="absolute top-0 left-0 w-full max-w-[640px] max-h-[310px] overflow-auto white-scrollbar min-h-[64px] bg-dark-input rounded-lg flex flex-col justify-between cursor-pointer border-2 border-primary-button z-20">
<div className="w-full flex flex-col gap-y-1">
<div className="flex items-center sticky top-0 border-b border-[#9CA3AF] mx-4 bg-dark-input">
<MagnifyingGlass
@ -137,7 +137,7 @@ export default function TextToSpeechProvider({ settings }) {
name="tts-provider-search"
autoComplete="off"
placeholder="Search text to speech providers"
className="-ml-4 my-2 bg-transparent z-20 pl-12 h-[38px] w-full px-4 py-1 text-sm outline-none focus:border-white text-white placeholder:text-white placeholder:font-medium"
className="-ml-4 my-2 bg-transparent z-20 pl-12 h-[38px] w-full px-4 py-1 text-sm outline-none text-white placeholder:text-white placeholder:font-medium"
onChange={(e) => setSearchQuery(e.target.value)}
ref={searchInputRef}
onKeyDown={(e) => {
@ -168,7 +168,7 @@ export default function TextToSpeechProvider({ settings }) {
</div>
) : (
<button
className="w-full max-w-[640px] h-[64px] bg-dark-input rounded-lg flex items-center p-[14px] justify-between cursor-pointer border-2 border-transparent hover:border-[#46C8FF] transition-all duration-300"
className="w-full max-w-[640px] h-[64px] bg-dark-input rounded-lg flex items-center p-[14px] justify-between cursor-pointer border-2 border-transparent hover:border-primary-button transition-all duration-300"
type="button"
onClick={() => setSearchMenuOpen(true)}
>

View File

@ -53,7 +53,7 @@ export default function ChatRow({ chat, onDelete }) {
<td className="px-6 py-4 flex items-center gap-x-6">
<button
onClick={handleDelete}
className="font-medium text-red-300 px-2 py-1 rounded-lg hover:bg-red-800 hover:bg-opacity-20"
className="font-medium px-2 py-1 rounded-lg hover:bg-sidebar-gradient text-white hover:text-white/80 hover:bg-opacity-20"
>
<Trash className="h-5 w-5" />
</button>

View File

@ -66,7 +66,7 @@ export default function ChatRow({ chat, onDelete }) {
<td className="px-6 py-4 flex items-center gap-x-6">
<button
onClick={handleDelete}
className="font-medium text-red-300 px-2 py-1 rounded-lg hover:bg-red-800 hover:bg-opacity-20"
className="font-medium px-2 py-1 rounded-lg hover:bg-sidebar-gradient text-white hover:text-white/80 hover:bg-opacity-20"
>
<Trash className="h-5 w-5" />
</button>

View File

@ -98,7 +98,7 @@ const ScriptTag = ({ embed }) => {
<button
disabled={copied}
onClick={handleClick}
className="disabled:border disabled:border-green-300 border border-transparent relative w-full font-mono flex bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white p-2.5"
className="disabled:border disabled:border-green-300 border border-transparent relative w-full font-mono flex bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none p-2.5"
>
<div
className="flex w-full text-left flex-col gap-y-1 pr-6 pl-4 whitespace-pre-line"

View File

@ -274,7 +274,7 @@ export const PermittedDomains = ({ defaultValue = [] }) => {
classNames={{
tag: "bg-blue-300/10 text-zinc-800 m-1",
input:
"flex bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white p-2.5",
"flex bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none p-2.5",
}}
/>
</div>
@ -293,7 +293,7 @@ export const NumberInput = ({ name, title, hint, defaultValue = 0 }) => {
<input
type="number"
name={name}
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-[15rem] p-2.5"
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-[15rem] p-2.5"
min={0}
defaultValue={defaultValue}
onScroll={(e) => e.target.blur()}

View File

@ -266,7 +266,7 @@ export default function GeneralEmbeddingPreference() {
/>
)}
{searchMenuOpen ? (
<div className="absolute top-0 left-0 w-full max-w-[640px] max-h-[310px] overflow-auto white-scrollbar min-h-[64px] bg-dark-input rounded-lg flex flex-col justify-between cursor-pointer border-2 border-[#46C8FF] z-20">
<div className="absolute top-0 left-0 w-full max-w-[640px] max-h-[310px] overflow-auto white-scrollbar min-h-[64px] bg-dark-input rounded-lg flex flex-col justify-between cursor-pointer border-2 border-primary-button z-20">
<div className="w-full flex flex-col gap-y-1">
<div className="flex items-center sticky top-0 border-b border-[#9CA3AF] mx-4 bg-dark-input">
<MagnifyingGlass
@ -279,7 +279,7 @@ export default function GeneralEmbeddingPreference() {
name="embedder-search"
autoComplete="off"
placeholder="Search all embedding providers"
className="-ml-4 my-2 bg-transparent z-20 pl-12 h-[38px] w-full px-4 py-1 text-sm outline-none focus:border-white text-white placeholder:text-white placeholder:font-medium"
className="-ml-4 my-2 bg-transparent z-20 pl-12 h-[38px] w-full px-4 py-1 text-sm outline-none text-white placeholder:text-white placeholder:font-medium"
onChange={(e) => setSearchQuery(e.target.value)}
ref={searchInputRef}
onKeyDown={(e) => {
@ -310,7 +310,7 @@ export default function GeneralEmbeddingPreference() {
</div>
) : (
<button
className="w-full max-w-[640px] h-[64px] bg-dark-input rounded-lg flex items-center p-[14px] justify-between cursor-pointer border-2 border-transparent hover:border-[#46C8FF] transition-all duration-300"
className="w-full max-w-[640px] h-[64px] bg-dark-input rounded-lg flex items-center p-[14px] justify-between cursor-pointer border-2 border-transparent hover:border-primary-button transition-all duration-300"
type="button"
onClick={() => setSearchMenuOpen(true)}
>

View File

@ -124,7 +124,7 @@ export default function EmbeddingTextSplitterPreference() {
min={1}
max={settings?.max_embed_chunk_size || 1000}
onWheel={(e) => e?.currentTarget?.blur()}
className="border-none bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="border-none bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="maximum length of vectorized text"
defaultValue={
isNullOrNaN(settings?.text_splitter_chunk_size)
@ -134,7 +134,7 @@ export default function EmbeddingTextSplitterPreference() {
required={true}
autoComplete="off"
/>
<p className="text-xs text-white/40">
<p className="text-xs text-white/40 mt-2">
{t("text.size.recommend")}{" "}
{numberWithCommas(settings?.max_embed_chunk_size || 1000)}.
</p>
@ -156,7 +156,7 @@ export default function EmbeddingTextSplitterPreference() {
name="text_splitter_chunk_overlap"
min={0}
onWheel={(e) => e?.currentTarget?.blur()}
className="border-none bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
className="border-none bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="maximum length of vectorized text"
defaultValue={
isNullOrNaN(settings?.text_splitter_chunk_overlap)

View File

@ -338,7 +338,7 @@ export default function GeneralLLMPreference() {
/>
)}
{searchMenuOpen ? (
<div className="absolute top-0 left-0 w-full max-w-[640px] max-h-[310px] overflow-auto white-scrollbar min-h-[64px] bg-dark-input rounded-lg flex flex-col justify-between cursor-pointer border-2 border-[#46C8FF] z-20">
<div className="absolute top-0 left-0 w-full max-w-[640px] max-h-[310px] overflow-auto white-scrollbar min-h-[64px] bg-dark-input rounded-lg flex flex-col justify-between cursor-pointer border-2 border-primary-button z-20">
<div className="w-full flex flex-col gap-y-1">
<div className="flex items-center sticky top-0 border-b border-[#9CA3AF] mx-4 bg-dark-input">
<MagnifyingGlass
@ -351,7 +351,7 @@ export default function GeneralLLMPreference() {
name="llm-search"
autoComplete="off"
placeholder="Search all LLM providers"
className="-ml-4 my-2 bg-transparent z-20 pl-12 h-[38px] w-full px-4 py-1 text-sm outline-none focus:border-white text-white placeholder:text-white placeholder:font-medium"
className="-ml-4 my-2 bg-transparent z-20 pl-12 h-[38px] w-full px-4 py-1 text-sm outline-none text-white placeholder:text-white placeholder:font-medium"
onChange={(e) => setSearchQuery(e.target.value)}
ref={searchInputRef}
onKeyDown={(e) => {
@ -385,7 +385,7 @@ export default function GeneralLLMPreference() {
</div>
) : (
<button
className="w-full max-w-[640px] h-[64px] bg-dark-input rounded-lg flex items-center p-[14px] justify-between cursor-pointer border-2 border-transparent hover:border-[#46C8FF] transition-all duration-300"
className="w-full max-w-[640px] h-[64px] bg-dark-input rounded-lg flex items-center p-[14px] justify-between cursor-pointer border-2 border-transparent hover:border-primary-button transition-all duration-300"
type="button"
onClick={() => setSearchMenuOpen(true)}
>

View File

@ -146,7 +146,7 @@ function MultiUserMode() {
<input
name="username"
type="text"
className="bg-zinc-900 text-white text-sm rounded-lg focus:border-blue-500 block w-full p-2.5 placeholder:text-white/20 focus:ring-blue-500"
className="bg-zinc-900 text-white text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5 placeholder:text-white/20 focus:ring-blue-500"
placeholder="Your admin username"
minLength={2}
required={true}
@ -165,7 +165,7 @@ function MultiUserMode() {
<input
name="password"
type="text"
className="bg-zinc-900 text-white text-sm rounded-lg focus:border-blue-500 block w-full p-2.5 placeholder:text-white/20 focus:ring-blue-500"
className="bg-zinc-900 text-white text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5 placeholder:text-white/20 focus:ring-blue-500"
placeholder="Your admin password"
minLength={8}
required={true}
@ -318,7 +318,7 @@ function PasswordProtection() {
<input
name="password"
type="text"
className="bg-zinc-900 text-white text-sm rounded-lg focus:border-blue-500 block w-full p-2.5 placeholder:text-white/20 focus:ring-blue-500"
className="bg-zinc-900 text-white text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5 placeholder:text-white/20"
placeholder="Your Instance Password"
minLength={8}
required={true}

View File

@ -148,7 +148,7 @@ export default function TranscriptionModelPreference() {
/>
)}
{searchMenuOpen ? (
<div className="absolute top-0 left-0 w-full max-w-[640px] max-h-[310px] overflow-auto white-scrollbar min-h-[64px] bg-dark-input rounded-lg flex flex-col justify-between cursor-pointer border-2 border-[#46C8FF] z-20">
<div className="absolute top-0 left-0 w-full max-w-[640px] max-h-[310px] overflow-auto white-scrollbar min-h-[64px] bg-dark-input rounded-lg flex flex-col justify-between cursor-pointer border-2 border-primary-button z-20">
<div className="w-full flex flex-col gap-y-1">
<div className="flex items-center sticky top-0 border-b border-[#9CA3AF] mx-4 bg-dark-input">
<MagnifyingGlass
@ -161,7 +161,7 @@ export default function TranscriptionModelPreference() {
name="provider-search"
autoComplete="off"
placeholder="Search audio transcription providers"
className="-ml-4 my-2 bg-transparent z-20 pl-12 h-[38px] w-full px-4 py-1 text-sm outline-none focus:border-white text-white placeholder:text-white placeholder:font-medium"
className="-ml-4 my-2 bg-transparent z-20 pl-12 h-[38px] w-full px-4 py-1 text-sm outline-none focus:outline-primary-button active:outline-primary-button outline-none text-white placeholder:text-white placeholder:font-medium"
onChange={(e) => setSearchQuery(e.target.value)}
ref={searchInputRef}
onKeyDown={(e) => {
@ -192,7 +192,7 @@ export default function TranscriptionModelPreference() {
</div>
) : (
<button
className="w-full max-w-[640px] h-[64px] bg-dark-input rounded-lg flex items-center p-[14px] justify-between cursor-pointer border-2 border-transparent hover:border-[#46C8FF] transition-all duration-300"
className="w-full max-w-[640px] h-[64px] bg-dark-input rounded-lg flex items-center p-[14px] justify-between cursor-pointer border-2 border-transparent hover:border-primary-button transition-all duration-300"
type="button"
onClick={() => setSearchMenuOpen(true)}
>

View File

@ -224,7 +224,7 @@ export default function GeneralVectorDatabase() {
/>
)}
{searchMenuOpen ? (
<div className="absolute top-0 left-0 w-full max-w-[640px] max-h-[310px] overflow-auto white-scrollbar min-h-[64px] bg-dark-input rounded-lg flex flex-col justify-between cursor-pointer border-2 border-[#46C8FF] z-20">
<div className="absolute top-0 left-0 w-full max-w-[640px] max-h-[310px] overflow-auto white-scrollbar min-h-[64px] bg-dark-input rounded-lg flex flex-col justify-between cursor-pointer border-2 border-primary-button z-20">
<div className="w-full flex flex-col gap-y-1">
<div className="flex items-center sticky top-0 border-b border-[#9CA3AF] mx-4 bg-dark-input">
<MagnifyingGlass
@ -237,7 +237,7 @@ export default function GeneralVectorDatabase() {
name="vdb-search"
autoComplete="off"
placeholder="Search all vector database providers"
className="-ml-4 my-2 bg-transparent z-20 pl-12 h-[38px] w-full px-4 py-1 text-sm outline-none focus:border-white text-white placeholder:text-white placeholder:font-medium"
className="-ml-4 my-2 bg-transparent z-20 pl-12 h-[38px] w-full px-4 py-1 text-sm outline-none text-white placeholder:text-white placeholder:font-medium"
onChange={(e) => setSearchQuery(e.target.value)}
ref={searchInputRef}
onKeyDown={(e) => {
@ -268,7 +268,7 @@ export default function GeneralVectorDatabase() {
</div>
) : (
<button
className="w-full max-w-[640px] h-[64px] bg-dark-input rounded-lg flex items-center p-[14px] justify-between cursor-pointer border-2 border-transparent hover:border-[#46C8FF] transition-all duration-300"
className="w-full max-w-[640px] h-[64px] bg-dark-input rounded-lg flex items-center p-[14px] justify-between cursor-pointer border-2 border-transparent hover:border-primary-button transition-all duration-300"
type="button"
onClick={() => setSearchMenuOpen(true)}
>

View File

@ -268,7 +268,7 @@ export default function LLMPreference({
<input
type="text"
placeholder="Search LLM providers"
className="bg-zinc-600 z-20 pl-10 h-[38px] rounded-full w-full px-4 py-1 text-sm border-2 border-slate-300/40 outline-none focus:border-white text-white"
className="bg-zinc-600 z-20 pl-10 h-[38px] rounded-full w-full px-4 py-1 text-sm border-2 border-slate-300/40 outline-none focus:outline-primary-button active:outline-primary-button outline-none text-white"
onChange={(e) => setSearchQuery(e.target.value)}
autoComplete="off"
onKeyDown={(e) => {

View File

@ -197,7 +197,7 @@ const JustMe = ({
<input
name="password"
type="password"
className="bg-zinc-900 text-white text-sm rounded-lg block w-full p-2.5"
className="bg-zinc-900 text-white text-sm rounded-lg block w-full p-2.5 focus:outline-primary-button active:outline-primary-button outline-none"
placeholder="Your admin password"
minLength={6}
required={true}
@ -280,7 +280,7 @@ const MyTeam = ({ setMultiUserLoginValid, myTeamSubmitRef, navigate }) => {
<input
name="username"
type="text"
className="bg-zinc-900 text-white text-sm rounded-lg block w-full p-2.5"
className="bg-zinc-900 text-white text-sm rounded-lg block w-full p-2.5 focus:outline-primary-button active:outline-primary-button outline-none"
placeholder="Your admin username"
minLength={6}
required={true}
@ -298,7 +298,7 @@ const MyTeam = ({ setMultiUserLoginValid, myTeamSubmitRef, navigate }) => {
<input
name="password"
type="password"
className="bg-zinc-900 text-white text-sm rounded-lg block w-full p-2.5"
className="bg-zinc-900 text-white text-sm rounded-lg block w-full p-2.5 focus:outline-primary-button active:outline-primary-button outline-none"
placeholder="Your admin password"
minLength={8}
required={true}

View File

@ -93,11 +93,11 @@ export function OnboardingLayout({ children }) {
<button
disabled={backBtn.disabled}
onClick={backBtn.onClick}
className="group p-2 rounded-lg border-2 border-zinc-300 disabled:border-zinc-600 h-fit w-fit disabled:not-allowed hover:bg-zinc-100 disabled:hover:bg-transparent"
className="group p-2 rounded-lg border-2 border-zinc-600 h-fit w-fit disabled:cursor-not-allowed hover:bg-zinc-100 disabled:hover:bg-transparent"
aria-label="Back"
>
<ArrowLeft
className="text-white group-hover:text-black group-disabled:text-gray-500"
className="group-hover:text-black text-gray-500"
size={30}
/>
</button>
@ -121,7 +121,7 @@ export function OnboardingLayout({ children }) {
<button
disabled={forwardBtn.disabled}
onClick={forwardBtn.onClick}
className="group p-2 rounded-lg border-2 border-zinc-300 disabled:border-zinc-600 h-fit w-fit disabled:not-allowed hover:bg-zinc-100 disabled:hover:bg-transparent"
className="group p-2 rounded-lg border-2 border-zinc-300 disabled:border-zinc-600 h-fit w-fit disabled:cursor-not-allowed hover:bg-zinc-100 disabled:hover:bg-transparent"
aria-label="Continue"
>
<ArrowRight

View File

@ -137,7 +137,7 @@ function SetupProvider({
<button
type="submit"
form="provider-form"
className="border-none text-xs px-2 py-1 font-semibold rounded-lg bg-primary-button hover:bg-secondary border-2 border-transparent hover:border-[#46C8FF] hover:text-white h-[32px] w-fit -mr-8 whitespace-nowrap shadow-[0_4px_14px_rgba(0,0,0,0.25)]"
className="border-none text-xs px-2 py-1 font-semibold rounded-lg bg-primary-button hover:bg-secondary border-2 border-transparent hover:border-primary-button hover:text-white h-[32px] w-fit -mr-8 whitespace-nowrap shadow-[0_4px_14px_rgba(0,0,0,0.25)]"
>
Save {LLMOption.name} settings
</button>

View File

@ -120,7 +120,7 @@ export default function AgentLLMSelection({
/>
)}
{searchMenuOpen ? (
<div className="absolute top-0 left-0 w-full max-w-[640px] max-h-[310px] overflow-auto white-scrollbar min-h-[64px] bg-dark-input rounded-lg flex flex-col justify-between cursor-pointer border-2 border-[#46C8FF] z-20">
<div className="absolute top-0 left-0 w-full max-w-[640px] max-h-[310px] overflow-auto white-scrollbar min-h-[64px] bg-dark-input rounded-lg flex flex-col justify-between cursor-pointer border-2 border-primary-button z-20">
<div className="w-full flex flex-col gap-y-1">
<div className="flex items-center sticky top-0 border-b border-[#9CA3AF] mx-4 bg-dark-input">
<MagnifyingGlass
@ -133,7 +133,7 @@ export default function AgentLLMSelection({
name="llm-search"
autoComplete="off"
placeholder="Search available LLM providers"
className="border-none -ml-4 my-2 bg-transparent z-20 pl-12 h-[38px] w-full px-4 py-1 text-sm outline-none focus:border-white text-white placeholder:text-white placeholder:font-medium"
className="border-none -ml-4 my-2 bg-transparent z-20 pl-12 h-[38px] w-full px-4 py-1 text-sm outline-none text-white placeholder:text-white placeholder:font-medium"
onChange={(e) => setSearchQuery(e.target.value)}
ref={searchInputRef}
onKeyDown={(e) => {
@ -165,7 +165,7 @@ export default function AgentLLMSelection({
</div>
) : (
<button
className="w-full max-w-[640px] h-[64px] bg-dark-input rounded-lg flex items-center p-[14px] justify-between cursor-pointer border-2 border-transparent hover:border-[#46C8FF] transition-all duration-300"
className="w-full max-w-[640px] h-[64px] bg-dark-input rounded-lg flex items-center p-[14px] justify-between cursor-pointer border-2 border-transparent hover:border-primary-button transition-all duration-300"
type="button"
onClick={() => setSearchMenuOpen(true)}
>

View File

@ -1,7 +1,9 @@
import useGetProviderModels, {
DISABLED_PROVIDERS,
} from "@/hooks/useGetProvidersModels";
import paths from "@/utils/paths";
import { useTranslation } from "react-i18next";
import { Link, useParams } from "react-router-dom";
// These models do NOT support function calling
function supportedModel(provider, model = "") {
@ -18,11 +20,32 @@ export default function AgentModelSelection({
workspace,
setHasChanges,
}) {
const { slug } = useParams();
const { defaultModels, customModels, loading } =
useGetProviderModels(provider);
const { t } = useTranslation();
if (DISABLED_PROVIDERS.includes(provider)) return null;
if (DISABLED_PROVIDERS.includes(provider)) {
return (
<div className="w-full h-10 justify-center items-center flex">
<p className="text-sm font-base text-white text-opacity-60 text-center">
Multi-model support is not supported for this provider yet.
<br />
Agent's will use{" "}
<Link
to={paths.workspace.settings.chatSettings(slug)}
className="underline"
>
the model set for the workspace
</Link>{" "}
or{" "}
<Link to={paths.settings.llmPreference()} className="underline">
the model set for the system.
</Link>
</p>
</div>
);
}
if (loading) {
return (

View File

@ -1,204 +0,0 @@
import React, { useEffect, useRef, useState } from "react";
import AnythingLLMIcon from "@/media/logo/anything-llm-icon.png";
import GoogleSearchIcon from "./icons/google.png";
import SerperDotDevIcon from "./icons/serper.png";
import BingSearchIcon from "./icons/bing.png";
import { CaretUpDown, MagnifyingGlass, X } from "@phosphor-icons/react";
import SearchProviderItem from "./SearchProviderItem";
import {
SerperDotDevOptions,
GoogleSearchOptions,
BingSearchOptions,
} from "./SearchProviderOptions";
import { useTranslation } from "react-i18next";
const SEARCH_PROVIDERS = [
{
name: "Please make a selection",
value: "none",
logo: AnythingLLMIcon,
options: () => <React.Fragment />,
description:
"Web search will be disabled until a provider and keys are provided.",
},
{
name: "Google Search Engine",
value: "google-search-engine",
logo: GoogleSearchIcon,
options: (settings) => <GoogleSearchOptions settings={settings} />,
description:
"Web search powered by a custom Google Search Engine. Free for 100 queries per day.",
},
{
name: "Serper.dev",
value: "serper-dot-dev",
logo: SerperDotDevIcon,
options: (settings) => <SerperDotDevOptions settings={settings} />,
description:
"Serper.dev web-search. Free account with a 2,500 calls, but then paid.",
},
{
name: "Bing Search",
value: "bing-search",
logo: BingSearchIcon,
options: (settings) => <BingSearchOptions settings={settings} />,
description:
"Web search powered by the Bing Search API. Free for 1000 queries per month.",
},
];
export default function AgentWebSearchSelection({
skill,
settings,
toggleSkill,
enabled = false,
}) {
const searchInputRef = useRef(null);
const [filteredResults, setFilteredResults] = useState([]);
const [selectedProvider, setSelectedProvider] = useState("none");
const [searchQuery, setSearchQuery] = useState("");
const [searchMenuOpen, setSearchMenuOpen] = useState(false);
const { t } = useTranslation();
function updateChoice(selection) {
setSearchQuery("");
setSelectedProvider(selection);
setSearchMenuOpen(false);
}
function handleXButton() {
if (searchQuery.length > 0) {
setSearchQuery("");
if (searchInputRef.current) searchInputRef.current.value = "";
} else {
setSearchMenuOpen(!searchMenuOpen);
}
}
useEffect(() => {
const filtered = SEARCH_PROVIDERS.filter((provider) =>
provider.name.toLowerCase().includes(searchQuery.toLowerCase())
);
setFilteredResults(filtered);
}, [searchQuery, selectedProvider]);
useEffect(() => {
setSelectedProvider(settings?.preferences?.agent_search_provider ?? "none");
}, [settings?.preferences?.agent_search_provider]);
const selectedSearchProviderObject = SEARCH_PROVIDERS.find(
(provider) => provider.value === selectedProvider
);
return (
<div className="border-b border-white/40 pb-4">
<div className="flex flex-col">
<div className="flex w-full justify-between items-center">
<label htmlFor="name" className="block input-label">
{t("agent.skill.web.title")}
</label>
<label className="border-none relative inline-flex cursor-pointer items-center mt-2">
<input
type="checkbox"
className="peer sr-only"
checked={enabled}
onClick={() => toggleSkill(skill)}
/>
<div className="pointer-events-none peer h-6 w-11 rounded-full bg-stone-400 after:absolute after:left-[2px] after:top-[2px] after:h-5 after:w-5 after:rounded-full after:shadow-xl after:border after:border-gray-600 after:bg-white after:box-shadow-md after:transition-all after:content-[''] peer-checked:bg-lime-300 peer-checked:after:translate-x-full peer-checked:after:border-white peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-blue-800"></div>
<span className="ml-3 text-sm font-medium text-gray-900 dark:text-gray-300"></span>
</label>
</div>
<p className="text-white text-opacity-60 text-xs font-medium py-1.5">
{t("agent.skill.web.desc-start")}
<br />
{t("agent.skill.web.desc-end")}
</p>
</div>
<div hidden={!enabled}>
<div className="relative">
<input
type="hidden"
name="system::agent_search_provider"
value={selectedProvider}
/>
{searchMenuOpen && (
<div
className="fixed top-0 left-0 w-full h-full bg-black bg-opacity-70 backdrop-blur-sm z-10"
onClick={() => setSearchMenuOpen(false)}
/>
)}
{searchMenuOpen ? (
<div className="absolute top-0 left-0 w-full max-w-[640px] max-h-[310px] overflow-auto white-scrollbar min-h-[64px] bg-[#18181B] rounded-lg flex flex-col justify-between cursor-pointer border-2 border-[#46C8FF] z-20">
<div className="w-full flex flex-col gap-y-1">
<div className="flex items-center sticky top-0 border-b border-[#9CA3AF] mx-4 bg-[#18181B]">
<MagnifyingGlass
size={20}
weight="bold"
className="absolute left-4 z-30 text-white -ml-4 my-2"
/>
<input
type="text"
name="web-provider-search"
autoComplete="off"
placeholder="Search available web-search providers"
className="border-none -ml-4 my-2 bg-transparent z-20 pl-12 h-[38px] w-full px-4 py-1 text-sm outline-none focus:border-white text-white placeholder:text-white placeholder:font-medium"
onChange={(e) => setSearchQuery(e.target.value)}
ref={searchInputRef}
onKeyDown={(e) => {
if (e.key === "Enter") e.preventDefault();
}}
/>
<X
size={20}
weight="bold"
className="cursor-pointer text-white hover:text-[#9CA3AF]"
onClick={handleXButton}
/>
</div>
<div className="flex-1 pl-4 pr-2 flex flex-col gap-y-1 overflow-y-auto white-scrollbar pb-4">
{filteredResults.map((provider) => {
return (
<SearchProviderItem
provider={provider}
key={provider.name}
checked={selectedProvider === provider.value}
onClick={() => updateChoice(provider.value)}
/>
);
})}
</div>
</div>
</div>
) : (
<button
className="w-full max-w-[640px] h-[64px] bg-[#18181B] rounded-lg flex items-center p-[14px] justify-between cursor-pointer border-2 border-transparent hover:border-[#46C8FF] transition-all duration-300"
type="button"
onClick={() => setSearchMenuOpen(true)}
>
<div className="flex gap-x-4 items-center">
<img
src={selectedSearchProviderObject.logo}
alt={`${selectedSearchProviderObject.name} logo`}
className="w-10 h-10 rounded-md"
/>
<div className="flex flex-col text-left">
<div className="text-sm font-semibold text-white">
{selectedSearchProviderObject.name}
</div>
<div className="mt-1 text-xs text-[#D2D5DB]">
{selectedSearchProviderObject.description}
</div>
</div>
</div>
<CaretUpDown size={24} weight="bold" className="text-white" />
</button>
)}
</div>
{selectedProvider !== "none" && (
<div className="mt-4 flex flex-col gap-y-1">
{selectedSearchProviderObject.options(settings)}
</div>
)}
</div>
</div>
);
}

View File

@ -2,6 +2,7 @@ import useGetProviderModels, {
DISABLED_PROVIDERS,
} from "@/hooks/useGetProvidersModels";
import { useTranslation } from "react-i18next";
export default function ChatModelSelection({
provider,
workspace,

View File

@ -137,7 +137,7 @@ function SetupProvider({
<button
type="submit"
form="provider-form"
className="text-xs px-2 py-1 font-semibold rounded-lg bg-primary-button hover:bg-secondary border-2 border-transparent hover:border-[#46C8FF] hover:text-white h-[32px] w-fit -mr-8 whitespace-nowrap shadow-[0_4px_14px_rgba(0,0,0,0.25)]"
className="text-xs px-2 py-1 font-semibold rounded-lg bg-primary-button hover:bg-secondary border-2 border-transparent hover:border-primary-button hover:text-white h-[32px] w-fit -mr-8 whitespace-nowrap shadow-[0_4px_14px_rgba(0,0,0,0.25)]"
>
Save {LLMOption.name} settings
</button>

View File

@ -3,8 +3,10 @@ import AnythingLLMIcon from "@/media/logo/anything-llm-icon.png";
import WorkspaceLLMItem from "./WorkspaceLLMItem";
import { AVAILABLE_LLM_PROVIDERS } from "@/pages/GeneralSettings/LLMPreference";
import { CaretUpDown, MagnifyingGlass, X } from "@phosphor-icons/react";
import ChatModelSelection from "../ChatModelSelection";
import ChatModelSelection from "./ChatModelSelection";
import { useTranslation } from "react-i18next";
import { Link } from "react-router-dom";
import paths from "@/utils/paths";
// Some providers can only be associated with a single model.
// In that case there is no selection to be made so we can just move on.
@ -80,7 +82,7 @@ export default function WorkspaceLLMSelection({
/>
)}
{searchMenuOpen ? (
<div className="absolute top-0 left-0 w-full max-w-[640px] max-h-[310px] overflow-auto white-scrollbar min-h-[64px] bg-dark-input rounded-lg flex flex-col justify-between cursor-pointer border-2 border-[#46C8FF] z-20">
<div className="absolute top-0 left-0 w-full max-w-[640px] max-h-[310px] overflow-auto white-scrollbar min-h-[64px] bg-dark-input rounded-lg flex flex-col justify-between cursor-pointer border-2 border-primary-button z-20">
<div className="w-full flex flex-col gap-y-1">
<div className="flex items-center sticky top-0 border-b border-[#9CA3AF] mx-4 bg-dark-input">
<MagnifyingGlass
@ -93,7 +95,7 @@ export default function WorkspaceLLMSelection({
name="llm-search"
autoComplete="off"
placeholder={t("chat.llm.search")}
className="-ml-4 my-2 bg-transparent z-20 pl-12 h-[38px] w-full px-4 py-1 text-sm outline-none focus:border-white text-white placeholder:text-white placeholder:font-medium"
className="-ml-4 my-2 bg-transparent z-20 pl-12 h-[38px] w-full px-4 py-1 text-sm outline-none focus:outline-primary-button active:outline-primary-button outline-none text-white placeholder:text-white placeholder:font-medium"
onChange={(e) => setSearchQuery(e.target.value)}
ref={searchInputRef}
onKeyDown={(e) => {
@ -125,7 +127,7 @@ export default function WorkspaceLLMSelection({
</div>
) : (
<button
className="w-full max-w-[640px] h-[64px] bg-dark-input rounded-lg flex items-center p-[14px] justify-between cursor-pointer border-2 border-transparent hover:border-[#46C8FF] transition-all duration-300"
className="w-full max-w-[640px] h-[64px] bg-dark-input rounded-lg flex items-center p-[14px] justify-between cursor-pointer border-2 border-transparent hover:border-primary-button transition-all duration-300"
type="button"
onClick={() => setSearchMenuOpen(true)}
>
@ -148,7 +150,22 @@ export default function WorkspaceLLMSelection({
</button>
)}
</div>
{!NO_MODEL_SELECTION.includes(selectedLLM) && (
{NO_MODEL_SELECTION.includes(selectedLLM) ? (
<>
{selectedLLM !== "default" && (
<div className="w-full h-10 justify-center items-center flex mt-4">
<p className="text-sm font-base text-white text-opacity-60 text-center">
Multi-model support is not supported for this provider yet.
<br />
This workspace will use{" "}
<Link to={paths.settings.llmPreference()} className="underline">
the model set for the system.
</Link>
</p>
</div>
)}
</>
) : (
<div className="mt-4 flex flex-col gap-y-1">
<ChatModelSelection
provider={selectedLLM}

View File

@ -152,7 +152,7 @@ export default function AddMemberModal({ closeModal, workspace, users }) {
</div>
<button
type="submit"
className="transition-all duration-300 text-xs px-2 py-1 font-semibold rounded-lg bg-primary-button hover:bg-secondary border-2 border-transparent hover:border-[#46C8FF] hover:text-white h-[32px] w-[68px] -mr-8 whitespace-nowrap shadow-[0_4px_14px_rgba(0,0,0,0.25)]"
className="transition-all duration-300 text-xs px-2 py-1 font-semibold rounded-lg bg-primary-button hover:bg-secondary border-2 border-transparent hover:border-primary-button hover:text-white h-[32px] w-[68px] -mr-8 whitespace-nowrap shadow-[0_4px_14px_rgba(0,0,0,0.25)]"
>
Save
</button>

View File

@ -10,6 +10,12 @@ const { USER_AGENT, WORKSPACE_AGENT } = require("./defaults");
class AgentHandler {
#invocationUUID;
#funcsToLoad = [];
#noProviderModelDefault = {
azure: "OPEN_MODEL_PREF",
lmstudio: "LMSTUDIO_MODEL_PREF",
textgenwebui: null, // does not even use `model` in API req
"generic-openai": "GENERIC_OPEN_AI_MODEL_PREF",
};
invocation = null;
aibitat = null;
channel = null;
@ -172,7 +178,7 @@ class AgentHandler {
case "mistral":
return "mistral-medium";
case "generic-openai":
return "gpt-3.5-turbo";
return null;
case "perplexity":
return "sonar-small-online";
case "textgenwebui":
@ -182,10 +188,30 @@ class AgentHandler {
}
}
/**
* Finds or assumes the model preference value to use for API calls.
* If multi-model loading is supported, we use their agent model selection of the workspace
* If not supported, we attempt to fallback to the system provider value for the LLM preference
* and if that fails - we assume a reasonable base model to exist.
* @returns {string} the model preference value to use in API calls
*/
#fetchModel() {
if (!Object.keys(this.#noProviderModelDefault).includes(this.provider))
return this.invocation.workspace.agentModel || this.#providerDefault();
// Provider has no reliable default (cant load many models) - so we need to look at system
// for the model param.
const sysModelKey = this.#noProviderModelDefault[this.provider];
if (!!sysModelKey)
return process.env[sysModelKey] ?? this.#providerDefault();
// If all else fails - look at the provider default list
return this.#providerDefault();
}
#providerSetupAndCheck() {
this.provider = this.invocation.workspace.agentProvider || "openai";
this.model =
this.invocation.workspace.agentModel || this.#providerDefault();
this.model = this.#fetchModel();
this.log(`Start ${this.#invocationUUID}::${this.provider}:${this.model}`);
this.#checkSetup();
}