2024-01-10 21:35:30 +01:00
|
|
|
const { togetherAiModels } = require("../AiProviders/togetherAi");
|
|
|
|
const SUPPORT_CUSTOM_MODELS = [
|
|
|
|
"openai",
|
|
|
|
"localai",
|
|
|
|
"ollama",
|
|
|
|
"native-llm",
|
|
|
|
"togetherai",
|
|
|
|
];
|
2023-10-31 19:38:28 +01:00
|
|
|
|
2023-11-14 21:31:44 +01:00
|
|
|
async function getCustomModels(provider = "", apiKey = null, basePath = null) {
|
2023-10-31 19:38:28 +01:00
|
|
|
if (!SUPPORT_CUSTOM_MODELS.includes(provider))
|
|
|
|
return { models: [], error: "Invalid provider for custom models" };
|
|
|
|
|
|
|
|
switch (provider) {
|
|
|
|
case "openai":
|
|
|
|
return await openAiModels(apiKey);
|
2023-11-14 21:31:44 +01:00
|
|
|
case "localai":
|
2023-12-11 23:18:28 +01:00
|
|
|
return await localAIModels(basePath, apiKey);
|
2023-12-28 02:21:47 +01:00
|
|
|
case "ollama":
|
|
|
|
return await ollamaAIModels(basePath, apiKey);
|
2024-01-10 21:35:30 +01:00
|
|
|
case "togetherai":
|
|
|
|
return await getTogetherAiModels();
|
2023-12-07 23:48:27 +01:00
|
|
|
case "native-llm":
|
|
|
|
return nativeLLMModels();
|
2023-10-31 19:38:28 +01:00
|
|
|
default:
|
|
|
|
return { models: [], error: "Invalid provider for custom models" };
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
async function openAiModels(apiKey = null) {
|
|
|
|
const { Configuration, OpenAIApi } = require("openai");
|
|
|
|
const config = new Configuration({
|
|
|
|
apiKey: apiKey || process.env.OPEN_AI_KEY,
|
|
|
|
});
|
|
|
|
const openai = new OpenAIApi(config);
|
|
|
|
const models = (
|
|
|
|
await openai
|
|
|
|
.listModels()
|
|
|
|
.then((res) => res.data.data)
|
|
|
|
.catch((e) => {
|
|
|
|
console.error(`OpenAI:listModels`, e.message);
|
|
|
|
return [];
|
|
|
|
})
|
|
|
|
).filter(
|
|
|
|
(model) => !model.owned_by.includes("openai") && model.owned_by !== "system"
|
|
|
|
);
|
|
|
|
|
2023-12-16 19:21:36 +01:00
|
|
|
// Api Key was successful so lets save it for future uses
|
|
|
|
if (models.length > 0 && !!apiKey) process.env.OPEN_AI_KEY = apiKey;
|
2023-10-31 19:38:28 +01:00
|
|
|
return { models, error: null };
|
|
|
|
}
|
|
|
|
|
2023-12-04 17:38:15 +01:00
|
|
|
async function localAIModels(basePath = null, apiKey = null) {
|
2023-11-14 21:31:44 +01:00
|
|
|
const { Configuration, OpenAIApi } = require("openai");
|
|
|
|
const config = new Configuration({
|
|
|
|
basePath,
|
2023-12-16 19:21:36 +01:00
|
|
|
apiKey: apiKey || process.env.LOCAL_AI_API_KEY,
|
2023-11-14 21:31:44 +01:00
|
|
|
});
|
|
|
|
const openai = new OpenAIApi(config);
|
|
|
|
const models = await openai
|
|
|
|
.listModels()
|
|
|
|
.then((res) => res.data.data)
|
|
|
|
.catch((e) => {
|
|
|
|
console.error(`LocalAI:listModels`, e.message);
|
|
|
|
return [];
|
|
|
|
});
|
|
|
|
|
2023-12-16 19:21:36 +01:00
|
|
|
// Api Key was successful so lets save it for future uses
|
|
|
|
if (models.length > 0 && !!apiKey) process.env.LOCAL_AI_API_KEY = apiKey;
|
2023-11-14 21:31:44 +01:00
|
|
|
return { models, error: null };
|
|
|
|
}
|
|
|
|
|
2023-12-28 02:21:47 +01:00
|
|
|
async function ollamaAIModels(basePath = null, _apiKey = null) {
|
|
|
|
let url;
|
|
|
|
try {
|
|
|
|
new URL(basePath);
|
|
|
|
if (basePath.split("").slice(-1)?.[0] === "/")
|
|
|
|
throw new Error("BasePath Cannot end in /!");
|
|
|
|
url = basePath;
|
|
|
|
} catch {
|
|
|
|
return { models: [], error: "Not a valid URL." };
|
|
|
|
}
|
|
|
|
|
|
|
|
const models = await fetch(`${url}/api/tags`)
|
|
|
|
.then((res) => {
|
|
|
|
if (!res.ok)
|
|
|
|
throw new Error(`Could not reach Ollama server! ${res.status}`);
|
|
|
|
return res.json();
|
|
|
|
})
|
|
|
|
.then((data) => data?.models || [])
|
|
|
|
.then((models) =>
|
|
|
|
models.map((model) => {
|
|
|
|
return { id: model.name };
|
|
|
|
})
|
|
|
|
)
|
|
|
|
.catch((e) => {
|
|
|
|
console.error(e);
|
|
|
|
return [];
|
|
|
|
});
|
|
|
|
|
|
|
|
return { models, error: null };
|
|
|
|
}
|
|
|
|
|
2024-01-10 21:35:30 +01:00
|
|
|
async function getTogetherAiModels() {
|
|
|
|
const knownModels = togetherAiModels();
|
|
|
|
if (!Object.keys(knownModels).length === 0)
|
|
|
|
return { models: [], error: null };
|
|
|
|
|
|
|
|
const models = Object.values(knownModels).map((model) => {
|
|
|
|
return {
|
|
|
|
id: model.id,
|
|
|
|
organization: model.organization,
|
|
|
|
name: model.name,
|
|
|
|
};
|
|
|
|
});
|
|
|
|
return { models, error: null };
|
|
|
|
}
|
|
|
|
|
2023-12-07 23:48:27 +01:00
|
|
|
function nativeLLMModels() {
|
|
|
|
const fs = require("fs");
|
|
|
|
const path = require("path");
|
|
|
|
const storageDir = path.resolve(
|
|
|
|
process.env.STORAGE_DIR
|
|
|
|
? path.resolve(process.env.STORAGE_DIR, "models", "downloaded")
|
|
|
|
: path.resolve(__dirname, `../../storage/models/downloaded`)
|
|
|
|
);
|
|
|
|
if (!fs.existsSync(storageDir))
|
|
|
|
return { models: [], error: "No model/downloaded storage folder found." };
|
|
|
|
|
|
|
|
const files = fs
|
|
|
|
.readdirSync(storageDir)
|
|
|
|
.filter((file) => file.toLowerCase().includes(".gguf"))
|
|
|
|
.map((file) => {
|
|
|
|
return { id: file, name: file };
|
|
|
|
});
|
|
|
|
return { models: files, error: null };
|
|
|
|
}
|
|
|
|
|
2023-10-31 19:38:28 +01:00
|
|
|
module.exports = {
|
|
|
|
getCustomModels,
|
|
|
|
};
|