θΏ™ζ˜―indexlocζδΎ›ηš„ζœεŠ‘οΌŒδΈθ¦θΎ“ε…₯任何密码
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 0 additions & 7 deletions server/utils/AiProviders/anthropic/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,13 +66,6 @@ class AnthropicLLM {
return validModels.includes(modelName);
}

// Moderation can be done with Anthropic, but its not really "exact" so we skip it
// https://docs.anthropic.com/claude/docs/content-moderation
async isSafe(_input = "") {
// Not implemented so must be stubbed
return { safe: true, reasons: [] };
}

constructPrompt({
systemPrompt = "",
contextTexts = [],
Expand Down
5 changes: 0 additions & 5 deletions server/utils/AiProviders/azureOpenAi/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,6 @@ class AzureOpenAiLLM {
return [prompt, ...chatHistory, { role: "user", content: userPrompt }];
}

async isSafe(_input = "") {
// Not implemented by Azure OpenAI so must be stubbed
return { safe: true, reasons: [] };
}

async getChatCompletion(messages = [], { temperature = 0.7 }) {
if (!this.model)
throw new Error(
Expand Down
5 changes: 0 additions & 5 deletions server/utils/AiProviders/cohere/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,11 +102,6 @@ class CohereLLM {
return [prompt, ...chatHistory, { role: "user", content: userPrompt }];
}

async isSafe(_input = "") {
// Not implemented so must be stubbed
return { safe: true, reasons: [] };
}

async getChatCompletion(messages = null, { temperature = 0.7 }) {
if (!(await this.isValidChatCompletionModel(this.model)))
throw new Error(
Expand Down
6 changes: 0 additions & 6 deletions server/utils/AiProviders/gemini/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -112,12 +112,6 @@ class GeminiLLM {
return validModels.includes(modelName);
}

// Moderation cannot be done with Gemini.
// Not implemented so must be stubbed
async isSafe(_input = "") {
return { safe: true, reasons: [] };
}

constructPrompt({
systemPrompt = "",
contextTexts = [],
Expand Down
5 changes: 0 additions & 5 deletions server/utils/AiProviders/genericOpenAi/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,11 +83,6 @@ class GenericOpenAiLLM {
return [prompt, ...chatHistory, { role: "user", content: userPrompt }];
}

async isSafe(_input = "") {
// Not implemented so must be stubbed
return { safe: true, reasons: [] };
}

async getChatCompletion(messages = null, { temperature = 0.7 }) {
const result = await this.openai.chat.completions
.create({
Expand Down
5 changes: 0 additions & 5 deletions server/utils/AiProviders/groq/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,11 +85,6 @@ class GroqLLM {
return [prompt, ...chatHistory, { role: "user", content: userPrompt }];
}

async isSafe(_input = "") {
// Not implemented so must be stubbed
return { safe: true, reasons: [] };
}

async getChatCompletion(messages = null, { temperature = 0.7 }) {
if (!(await this.isValidChatCompletionModel(this.model)))
throw new Error(
Expand Down
5 changes: 0 additions & 5 deletions server/utils/AiProviders/huggingface/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,6 @@ class HuggingFaceLLM {
];
}

async isSafe(_input = "") {
// Not implemented so must be stubbed
return { safe: true, reasons: [] };
}

async getChatCompletion(messages = null, { temperature = 0.7 }) {
const result = await this.openai.createChatCompletion({
model: this.model,
Expand Down
5 changes: 0 additions & 5 deletions server/utils/AiProviders/koboldCPP/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,6 @@ class KoboldCPPLLM {
return [prompt, ...chatHistory, { role: "user", content: userPrompt }];
}

async isSafe(_input = "") {
// Not implemented so must be stubbed
return { safe: true, reasons: [] };
}

async getChatCompletion(messages = null, { temperature = 0.7 }) {
const result = await this.openai.chat.completions
.create({
Expand Down
5 changes: 0 additions & 5 deletions server/utils/AiProviders/liteLLM/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,6 @@ class LiteLLM {
return [prompt, ...chatHistory, { role: "user", content: userPrompt }];
}

async isSafe(_input = "") {
// Not implemented so must be stubbed
return { safe: true, reasons: [] };
}

async getChatCompletion(messages = null, { temperature = 0.7 }) {
const result = await this.openai.chat.completions
.create({
Expand Down
5 changes: 0 additions & 5 deletions server/utils/AiProviders/lmStudio/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,6 @@ class LMStudioLLM {
return [prompt, ...chatHistory, { role: "user", content: userPrompt }];
}

async isSafe(_input = "") {
// Not implemented so must be stubbed
return { safe: true, reasons: [] };
}

async getChatCompletion(messages = null, { temperature = 0.7 }) {
if (!this.model)
throw new Error(
Expand Down
5 changes: 0 additions & 5 deletions server/utils/AiProviders/localAi/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,6 @@ class LocalAiLLM {
return [prompt, ...chatHistory, { role: "user", content: userPrompt }];
}

async isSafe(_input = "") {
// Not implemented so must be stubbed
return { safe: true, reasons: [] };
}

async getChatCompletion(messages = null, { temperature = 0.7 }) {
if (!(await this.isValidChatCompletionModel(this.model)))
throw new Error(
Expand Down
4 changes: 0 additions & 4 deletions server/utils/AiProviders/mistral/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,6 @@ class MistralLLM {
return [prompt, ...chatHistory, { role: "user", content: userPrompt }];
}

async isSafe(_ = "") {
return { safe: true, reasons: [] };
}

async getChatCompletion(messages = null, { temperature = 0.7 }) {
if (!(await this.isValidChatCompletionModel(this.model)))
throw new Error(
Expand Down
5 changes: 0 additions & 5 deletions server/utils/AiProviders/native/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -117,11 +117,6 @@ class NativeLLM {
return [prompt, ...chatHistory, { role: "user", content: userPrompt }];
}

async isSafe(_input = "") {
// Not implemented so must be stubbed
return { safe: true, reasons: [] };
}

async getChatCompletion(messages = null, { temperature = 0.7 }) {
const model = await this.#llamaClient({ temperature });
const response = await model.call(messages);
Expand Down
5 changes: 0 additions & 5 deletions server/utils/AiProviders/ollama/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -99,11 +99,6 @@ class OllamaAILLM {
return [prompt, ...chatHistory, { role: "user", content: userPrompt }];
}

async isSafe(_input = "") {
// Not implemented so must be stubbed
return { safe: true, reasons: [] };
}

async getChatCompletion(messages = null, { temperature = 0.7 }) {
const model = this.#ollamaClient({ temperature });
const textResponse = await model
Expand Down
31 changes: 0 additions & 31 deletions server/utils/AiProviders/openAi/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,37 +86,6 @@ class OpenAiLLM {
return [prompt, ...chatHistory, { role: "user", content: userPrompt }];
}

async isSafe(input = "") {
const { flagged = false, categories = {} } = await this.openai.moderations
.create({ input })
.then((res) => {
if (!res.hasOwnProperty("results"))
throw new Error("OpenAI moderation: No results!");
if (res.results.length === 0)
throw new Error("OpenAI moderation: No results length!");
return res.results[0];
})
.catch((error) => {
throw new Error(
`OpenAI::CreateModeration failed with: ${error.message}`
);
});

if (!flagged) return { safe: true, reasons: [] };
const reasons = Object.keys(categories)
.map((category) => {
const value = categories[category];
if (value === true) {
return category.replace("/", " or ");
} else {
return null;
}
})
.filter((reason) => !!reason);

return { safe: false, reasons };
}

async getChatCompletion(messages = null, { temperature = 0.7 }) {
if (!(await this.isValidChatCompletionModel(this.model)))
throw new Error(
Expand Down
5 changes: 0 additions & 5 deletions server/utils/AiProviders/openRouter/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -124,11 +124,6 @@ class OpenRouterLLM {
return [prompt, ...chatHistory, { role: "user", content: userPrompt }];
}

async isSafe(_input = "") {
// Not implemented so must be stubbed
return { safe: true, reasons: [] };
}

async getChatCompletion(messages = null, { temperature = 0.7 }) {
if (!(await this.isValidChatCompletionModel(this.model)))
throw new Error(
Expand Down
5 changes: 0 additions & 5 deletions server/utils/AiProviders/perplexity/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,6 @@ class PerplexityLLM {
return [prompt, ...chatHistory, { role: "user", content: userPrompt }];
}

async isSafe(_input = "") {
// Not implemented so must be stubbed
return { safe: true, reasons: [] };
}

async getChatCompletion(messages = null, { temperature = 0.7 }) {
if (!(await this.isValidChatCompletionModel(this.model)))
throw new Error(
Expand Down
5 changes: 0 additions & 5 deletions server/utils/AiProviders/textGenWebUI/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,6 @@ class TextGenWebUILLM {
return [prompt, ...chatHistory, { role: "user", content: userPrompt }];
}

async isSafe(_input = "") {
// Not implemented so must be stubbed
return { safe: true, reasons: [] };
}

async getChatCompletion(messages = null, { temperature = 0.7 }) {
const result = await this.openai.chat.completions
.create({
Expand Down
5 changes: 0 additions & 5 deletions server/utils/AiProviders/togetherAi/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,6 @@ class TogetherAiLLM {
return [prompt, ...chatHistory, { role: "user", content: userPrompt }];
}

async isSafe(_input = "") {
// Not implemented so must be stubbed
return { safe: true, reasons: [] };
}

async getChatCompletion(messages = null, { temperature = 0.7 }) {
if (!(await this.isValidChatCompletionModel(this.model)))
throw new Error(
Expand Down
14 changes: 0 additions & 14 deletions server/utils/chats/embed.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,20 +33,6 @@ async function streamChatWithForEmbed(
model: chatModel ?? embed.workspace?.chatModel,
});
const VectorDb = getVectorDbClass();
const { safe, reasons = [] } = await LLMConnector.isSafe(message);
if (!safe) {
writeResponseChunk(response, {
id: uuid,
type: "abort",
textResponse: null,
sources: [],
close: true,
error: `This message was moderated and will not be allowed. Violations for ${reasons.join(
", "
)} found.`,
});
return;
}

const messageLimit = 20;
const hasVectorizedSpace = await VectorDb.hasNamespace(embed.workspace.slug);
Expand Down
13 changes: 0 additions & 13 deletions server/utils/chats/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,19 +56,6 @@ async function chatWithWorkspace(
model: workspace?.chatModel,
});
const VectorDb = getVectorDbClass();
const { safe, reasons = [] } = await LLMConnector.isSafe(message);
if (!safe) {
return {
id: uuid,
type: "abort",
textResponse: null,
sources: [],
close: true,
error: `This message was moderated and will not be allowed. Violations for ${reasons.join(
", "
)} found.`,
};
}

const messageLimit = workspace?.openAiHistory || 20;
const hasVectorizedSpace = await VectorDb.hasNamespace(workspace.slug);
Expand Down
14 changes: 0 additions & 14 deletions server/utils/chats/stream.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,20 +53,6 @@ async function streamChatWithWorkspace(
model: workspace?.chatModel,
});
const VectorDb = getVectorDbClass();
const { safe, reasons = [] } = await LLMConnector.isSafe(message);
if (!safe) {
writeResponseChunk(response, {
id: uuid,
type: "abort",
textResponse: null,
sources: [],
close: true,
error: `This message was moderated and will not be allowed. Violations for ${reasons.join(
", "
)} found.`,
});
return;
}

const messageLimit = workspace?.openAiHistory || 20;
const hasVectorizedSpace = await VectorDb.hasNamespace(workspace.slug);
Expand Down
52 changes: 52 additions & 0 deletions server/utils/helpers/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,46 @@
/**
* @typedef {Object} BaseLLMProvider - A basic llm provider object
* @property {Function} streamingEnabled - Checks if streaming is enabled for chat completions.
* @property {Function} promptWindowLimit - Returns the token limit for the current model.
* @property {Function} isValidChatCompletionModel - Validates if the provided model is suitable for chat completion.
* @property {Function} constructPrompt - Constructs a formatted prompt for the chat completion request.
* @property {Function} getChatCompletion - Gets a chat completion response from OpenAI.
* @property {Function} streamGetChatCompletion - Streams a chat completion response from OpenAI.
* @property {Function} handleStream - Handles the streaming response.
* @property {Function} embedTextInput - Embeds the provided text input using the specified embedder.
* @property {Function} embedChunks - Embeds multiple chunks of text using the specified embedder.
* @property {Function} compressMessages - Compresses chat messages to fit within the token limit.
*/

/**
* @typedef {Object} BaseVectorDatabaseProvider
* @property {string} name - The name of the Vector Database instance.
* @property {Function} connect - Connects to the Vector Database client.
* @property {Function} totalVectors - Returns the total number of vectors in the database.
* @property {Function} namespaceCount - Returns the count of vectors in a given namespace.
* @property {Function} similarityResponse - Performs a similarity search on a given namespace.
* @property {Function} namespace - Retrieves the specified namespace collection.
* @property {Function} hasNamespace - Checks if a namespace exists.
* @property {Function} namespaceExists - Verifies if a namespace exists in the client.
* @property {Function} deleteVectorsInNamespace - Deletes all vectors in a specified namespace.
* @property {Function} deleteDocumentFromNamespace - Deletes a document from a specified namespace.
* @property {Function} addDocumentToNamespace - Adds a document to a specified namespace.
* @property {Function} performSimilaritySearch - Performs a similarity search in the namespace.
*/

/**
* @typedef {Object} BaseEmbedderProvider
* @property {string} model - The model used for embedding.
* @property {number} maxConcurrentChunks - The maximum number of chunks processed concurrently.
* @property {number} embeddingMaxChunkLength - The maximum length of each chunk for embedding.
* @property {Function} embedTextInput - Embeds a single text input.
* @property {Function} embedChunks - Embeds multiple chunks of text.
*/

/**
* Gets the systems current vector database provider.
* @returns { BaseVectorDatabaseProvider}
*/
function getVectorDbClass() {
const vectorSelection = process.env.VECTOR_DB || "lancedb";
switch (vectorSelection) {
Expand Down Expand Up @@ -30,6 +73,11 @@ function getVectorDbClass() {
}
}

/**
* Returns the LLMProvider with its embedder attached via system or via defined provider.
* @param {{provider: string | null, model: string | null} | null} params - Initialize params for LLMs provider
* @returns {BaseLLMProvider}
*/
function getLLMProvider({ provider = null, model = null } = {}) {
const LLMSelection = provider ?? process.env.LLM_PROVIDER ?? "openai";
const embedder = getEmbeddingEngineSelection();
Expand Down Expand Up @@ -99,6 +147,10 @@ function getLLMProvider({ provider = null, model = null } = {}) {
}
}

/**
* Returns the EmbedderProvider by itself to whatever is currently in the system settings.
* @returns {BaseEmbedderProvider}
*/
function getEmbeddingEngineSelection() {
const { NativeEmbedder } = require("../EmbeddingEngines/native");
const engineSelection = process.env.EMBEDDING_ENGINE;
Expand Down