diff --git a/.vscode/settings.json b/.vscode/settings.json index 14efd3fae..307bbe6c7 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -33,6 +33,7 @@ "Mintplex", "mixtral", "moderations", + "novita", "numpages", "Ollama", "Oobabooga", diff --git a/README.md b/README.md index b1f308a14..861e4fa59 100644 --- a/README.md +++ b/README.md @@ -96,6 +96,7 @@ AnythingLLM divides your documents into objects called `workspaces`. A Workspace - [Text Generation Web UI](https://github.com/oobabooga/text-generation-webui) - [Apipie](https://apipie.ai/) - [xAI](https://x.ai/) +- [Novita AI (chat models)](https://novita.ai/model-api/product/llm-api?utm_source=github_anything-llm&utm_medium=github_readme&utm_campaign=link) **Embedder models:** @@ -150,7 +151,7 @@ This monorepo consists of three main sections: Mintplex Labs & the community maintain a number of deployment methods, scripts, and templates that you can use to run AnythingLLM locally. Refer to the table below to read how to deploy on your preferred environment or to automatically deploy. | Docker | AWS | GCP | Digital Ocean | Render.com | -|----------------------------------------|----:|-----|---------------|------------| +|----------------------------------------|----|-----|---------------|------------| | [![Deploy on Docker][docker-btn]][docker-deploy] | [![Deploy on AWS][aws-btn]][aws-deploy] | [![Deploy on GCP][gcp-btn]][gcp-deploy] | [![Deploy on DigitalOcean][do-btn]][do-deploy] | [![Deploy on Render.com][render-btn]][render-deploy] | | Railway | RepoCloud | Elestio | diff --git a/collector/extensions/index.js b/collector/extensions/index.js index 47989d5d5..81a3a3dd7 100644 --- a/collector/extensions/index.js +++ b/collector/extensions/index.js @@ -118,8 +118,7 @@ function extensions(app) { try { const websiteDepth = require("../utils/extensions/WebsiteDepth"); const { url, depth = 1, maxLinks = 20 } = reqBody(request); - if (!validURL(url)) return { success: false, reason: "Not a valid URL." }; - + if (!validURL(url)) throw new Error("Not a valid URL."); const scrapedData = await websiteDepth(url, depth, maxLinks); response.status(200).json({ success: true, data: scrapedData }); } catch (e) { diff --git a/collector/utils/files/mime.js b/collector/utils/files/mime.js index ad3ff5782..b3f03b131 100644 --- a/collector/utils/files/mime.js +++ b/collector/utils/files/mime.js @@ -38,6 +38,7 @@ class MimeDetector { "pas", "r", "go", + "ino", ], }, true @@ -47,7 +48,7 @@ class MimeDetector { // These are file types that are not detected by the mime library and need to be processed as text files. // You should only add file types that are not detected by the mime library, are parsable as text, and are files // with no extension. Otherwise, their extension should be added to the overrides array. - #specialTextFileTypes = ["dockerfile", "jenkinsfile"]; + #specialTextFileTypes = ["dockerfile", "jenkinsfile", "dockerignore"]; /** * Returns the MIME type of the file. If the file has no extension found, it will be processed as a text file. diff --git a/collector/utils/url/index.js b/collector/utils/url/index.js index 8a58dbd7a..c9d87b295 100644 --- a/collector/utils/url/index.js +++ b/collector/utils/url/index.js @@ -1,7 +1,7 @@ /** ATTN: SECURITY RESEARCHERS * To Security researchers about to submit an SSRF report CVE - please don't. * We are aware that the code below is does not defend against any of the thousands of ways - * you can map a hostname to another IP. The code below does not have intention of blocking this + * you can map a hostname to another IP via tunneling, hosts editing, etc. The code below does not have intention of blocking this * and is simply to prevent the user from accidentally putting in non-valid websites, which is all this protects * since _all urls must be submitted by the user anyway_ and cannot be done with authentication and manager or admin roles. * If an attacker has those roles then the system is already vulnerable and this is not a primary concern. @@ -14,15 +14,29 @@ const VALID_PROTOCOLS = ["https:", "http:"]; const INVALID_OCTETS = [192, 172, 10, 127]; +/** + * If an ip address is passed in the user is attempting to collector some internal service running on internal/private IP. + * This is not a security feature and simply just prevents the user from accidentally entering invalid IP addresses. + * @param {URL} param0 + * @param {URL['hostname']} param0.hostname + * @returns {boolean} + */ function isInvalidIp({ hostname }) { const IPRegex = new RegExp( /^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/gi ); + + // Not an IP address at all - passthrough if (!IPRegex.test(hostname)) return false; const [octetOne, ..._rest] = hostname.split("."); // If fails to validate to number - abort and return as invalid. if (isNaN(Number(octetOne))) return true; + + // Allow localhost loopback and 0.0.0.0 for scraping convenience + // for locally hosted services or websites + if (["127.0.0.1", "0.0.0.0"].includes(hostname)) return false; + return INVALID_OCTETS.includes(Number(octetOne)); } diff --git a/docker/.env.example b/docker/.env.example index 7bb07ebef..058046596 100644 --- a/docker/.env.example +++ b/docker/.env.example @@ -90,6 +90,10 @@ GID='1000' # LITE_LLM_BASE_PATH='http://127.0.0.1:4000' # LITE_LLM_API_KEY='sk-123abc' +# LLM_PROVIDER='novita' +# NOVITA_LLM_API_KEY='your-novita-api-key-here' check on https://novita.ai/settings#key-management +# NOVITA_LLM_MODEL_PREF='gryphe/mythomax-l2-13b' + # LLM_PROVIDER='cohere' # COHERE_API_KEY= # COHERE_MODEL_PREF='command-r' @@ -291,4 +295,8 @@ GID='1000' # Disable viewing chat history from the UI and frontend APIs. # See https://docs.anythingllm.com/configuration#disable-view-chat-history for more information. -# DISABLE_VIEW_CHAT_HISTORY=1 \ No newline at end of file +# DISABLE_VIEW_CHAT_HISTORY=1 + +# Enable simple SSO passthrough to pre-authenticate users from a third party service. +# See https://docs.anythingllm.com/configuration#simple-sso-passthrough for more information. +# SIMPLE_SSO_ENABLED=1 \ No newline at end of file diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx index cb3bac7f7..6ce42fadb 100644 --- a/frontend/src/App.jsx +++ b/frontend/src/App.jsx @@ -9,6 +9,7 @@ import PrivateRoute, { import { ToastContainer } from "react-toastify"; import "react-toastify/dist/ReactToastify.css"; import Login from "@/pages/Login"; +import SimpleSSOPassthrough from "@/pages/Login/SSO/simple"; import OnboardingFlow from "@/pages/OnboardingFlow"; import i18n from "./i18n"; @@ -77,6 +78,8 @@ export default function App() { } /> } /> + } /> + } diff --git a/frontend/src/components/LLMSelection/AnthropicAiOptions/index.jsx b/frontend/src/components/LLMSelection/AnthropicAiOptions/index.jsx index 08b283813..d66d36673 100644 --- a/frontend/src/components/LLMSelection/AnthropicAiOptions/index.jsx +++ b/frontend/src/components/LLMSelection/AnthropicAiOptions/index.jsx @@ -34,8 +34,12 @@ export default function AnthropicAiOptions({ settings }) { "claude-2.0", "claude-2.1", "claude-3-haiku-20240307", - "claude-3-opus-20240229", "claude-3-sonnet-20240229", + "claude-3-opus-latest", + "claude-3-5-haiku-latest", + "claude-3-5-haiku-20241022", + "claude-3-5-sonnet-latest", + "claude-3-5-sonnet-20241022", "claude-3-5-sonnet-20240620", ].map((model) => { return ( diff --git a/frontend/src/components/LLMSelection/AwsBedrockLLMOptions/index.jsx b/frontend/src/components/LLMSelection/AwsBedrockLLMOptions/index.jsx index 00f44a35f..569ec4395 100644 --- a/frontend/src/components/LLMSelection/AwsBedrockLLMOptions/index.jsx +++ b/frontend/src/components/LLMSelection/AwsBedrockLLMOptions/index.jsx @@ -1,7 +1,12 @@ import { ArrowSquareOut, Info } from "@phosphor-icons/react"; import { AWS_REGIONS } from "./regions"; +import { useState } from "react"; export default function AwsBedrockLLMOptions({ settings }) { + const [useSessionToken, setUseSessionToken] = useState( + settings?.AwsBedrockLLMConnectionMethod === "sessionToken" + ); + return (
{!settings?.credentialsOnly && ( @@ -24,6 +29,43 @@ export default function AwsBedrockLLMOptions({ settings }) {
)} +
+ +
+ +

+ Select the method to authenticate with AWS Bedrock. +

+
+
+ + IAM + + + + Session Token + +
+
+
+ {useSessionToken && ( +
+ + +
+ )}