diff --git a/.vscode/settings.json b/.vscode/settings.json index 60ff747fd..5e26e4778 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -31,7 +31,6 @@ "Mintplex", "moderations", "numpages", - "odbc", "Ollama", "Oobabooga", "openai", diff --git a/docker/Dockerfile b/docker/Dockerfile index c02c34794..f04036831 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -19,7 +19,7 @@ RUN DEBIAN_FRONTEND=noninteractive apt-get update && \ libgcc1 libglib2.0-0 libgtk-3-0 libnspr4 libpango-1.0-0 libx11-6 libx11-xcb1 libxcb1 \ libxcomposite1 libxcursor1 libxdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 \ libxss1 libxtst6 ca-certificates fonts-liberation libappindicator1 libnss3 lsb-release \ - xdg-utils git build-essential ffmpeg unixodbc unixodbc-dev && \ + xdg-utils git build-essential ffmpeg && \ mkdir -p /etc/apt/keyrings && \ curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg && \ echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_18.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list && \ @@ -79,7 +79,7 @@ RUN DEBIAN_FRONTEND=noninteractive apt-get update && \ libgcc1 libglib2.0-0 libgtk-3-0 libnspr4 libpango-1.0-0 libx11-6 libx11-xcb1 libxcb1 \ libxcomposite1 libxcursor1 libxdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 \ libxss1 libxtst6 ca-certificates fonts-liberation libappindicator1 libnss3 lsb-release \ - xdg-utils git build-essential ffmpeg unixodbc unixodbc-dev && \ + xdg-utils git build-essential ffmpeg && \ mkdir -p /etc/apt/keyrings && \ curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg && \ echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_18.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list && \ diff --git a/frontend/src/pages/Admin/Agents/SQLConnectorSelection/DBConnection.jsx b/frontend/src/pages/Admin/Agents/SQLConnectorSelection/DBConnection.jsx index d7361baea..9d7b35b0a 100644 --- a/frontend/src/pages/Admin/Agents/SQLConnectorSelection/DBConnection.jsx +++ b/frontend/src/pages/Admin/Agents/SQLConnectorSelection/DBConnection.jsx @@ -1,14 +1,12 @@ import PostgreSQLLogo from "./icons/postgresql.png"; import MySQLLogo from "./icons/mysql.png"; import MSSQLLogo from "./icons/mssql.png"; -import ODBCLogo from "./icons/odbc.png"; import { X } from "@phosphor-icons/react"; export const DB_LOGOS = { postgresql: PostgreSQLLogo, mysql: MySQLLogo, "sql-server": MSSQLLogo, - odbc: ODBCLogo, }; export default function DBConnection({ connection, onRemove, setHasChanges }) { diff --git a/frontend/src/pages/Admin/Agents/SQLConnectorSelection/NewConnectionModal.jsx b/frontend/src/pages/Admin/Agents/SQLConnectorSelection/NewConnectionModal.jsx index f6b1c21e3..e5f4c3016 100644 --- a/frontend/src/pages/Admin/Agents/SQLConnectorSelection/NewConnectionModal.jsx +++ b/frontend/src/pages/Admin/Agents/SQLConnectorSelection/NewConnectionModal.jsx @@ -11,7 +11,6 @@ function assembleConnectionString({ host = "", port = "", database = "", - driver = "", }) { if ([username, password, host, database].every((i) => !!i) === false) return `Please fill out all the fields above.`; @@ -22,9 +21,6 @@ function assembleConnectionString({ return `mysql://${username}:${password}@${host}:${port}/${database}`; case "sql-server": return `mssql://${username}:${password}@${host}:${port}/${database}`; - case "odbc": - if (!driver) return `Please fill out the driver field.`; - return `Driver={${driver}};Server=${host};Port=${port};Database=${database};UID=${username};PWD=${password}`; default: return null; } @@ -37,7 +33,6 @@ const DEFAULT_CONFIG = { host: null, port: null, database: null, - driver: null, }; export default function NewSQLConnection({ isOpen, closeModal, onSubmit }) { @@ -53,14 +48,12 @@ export default function NewSQLConnection({ isOpen, closeModal, onSubmit }) { function onFormChange() { const form = new FormData(document.getElementById("sql-connection-form")); - setConfig({ username: form.get("username").trim(), password: form.get("password"), host: form.get("host").trim(), port: form.get("port").trim(), database: form.get("database").trim(), - driver: form.get("driver")?.trim(), }); } @@ -81,7 +74,7 @@ export default function NewSQLConnection({ isOpen, closeModal, onSubmit }) { // to the parent container form so we don't have nested forms. return createPortal( <ModalWrapper isOpen={isOpen}> - <div className="relative w-full md:w-fit max-w-2xl max-h-full md:mt-8"> + <div className="relative w-full md:w-1/3 max-w-2xl max-h-full md:mt-8"> <div className="relative bg-main-gradient rounded-xl shadow-[0_4px_14px_rgba(0,0,0,0.25)] max-h-[85vh] overflow-y-scroll no-scroll"> <div className="flex items-start justify-between p-4 border-b rounded-t border-gray-500/50"> <h3 className="text-xl font-semibold text-white"> @@ -121,7 +114,7 @@ export default function NewSQLConnection({ isOpen, closeModal, onSubmit }) { <label className="text-white text-sm font-semibold block my-4"> Select your SQL engine </label> - <div className="flex flex-wrap gap-x-4 gap-y-4"> + <div className="grid md:grid-cols-4 gap-4 grid-cols-2"> <DBEngine provider="postgresql" active={engine === "postgresql"} @@ -137,11 +130,6 @@ export default function NewSQLConnection({ isOpen, closeModal, onSubmit }) { active={engine === "sql-server"} onClick={() => setEngine("sql-server")} /> - <DBEngine - provider="odbc" - active={engine === "odbc"} - onClick={() => setEngine("odbc")} - /> </div> </div> @@ -236,23 +224,6 @@ export default function NewSQLConnection({ isOpen, closeModal, onSubmit }) { spellCheck={false} /> </div> - - {engine === "odbc" && ( - <div className="flex flex-col"> - <label className="text-white text-sm font-semibold block mb-3"> - Driver - </label> - <input - type="text" - name="driver" - 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 driver to use eg: MongoDB ODBC 1.2.0 ANSI Driver" - required={true} - autoComplete="off" - spellCheck={false} - /> - </div> - )} <p className="text-white/40 text-sm"> {assembleConnectionString({ engine, ...config })} </p> diff --git a/frontend/src/pages/Admin/Agents/SQLConnectorSelection/icons/odbc.png b/frontend/src/pages/Admin/Agents/SQLConnectorSelection/icons/odbc.png deleted file mode 100644 index c28755887..000000000 Binary files a/frontend/src/pages/Admin/Agents/SQLConnectorSelection/icons/odbc.png and /dev/null differ diff --git a/server/package.json b/server/package.json index 8cd3d7aa1..ee08d53e0 100644 --- a/server/package.json +++ b/server/package.json @@ -67,7 +67,6 @@ "mysql2": "^3.9.8", "node-html-markdown": "^1.3.0", "node-llama-cpp": "^2.8.0", - "odbc": "^2.4.8", "ollama": "^0.5.0", "openai": "4.38.5", "pg": "^8.11.5", diff --git a/server/utils/agents/aibitat/plugins/sql-agent/SQLConnectors/ODBC.js b/server/utils/agents/aibitat/plugins/sql-agent/SQLConnectors/ODBC.js deleted file mode 100644 index d4f58464e..000000000 --- a/server/utils/agents/aibitat/plugins/sql-agent/SQLConnectors/ODBC.js +++ /dev/null @@ -1,60 +0,0 @@ -const odbc = require("odbc"); -const UrlPattern = require("url-pattern"); - -class ODBCConnector { - #connected = false; - database_id = ""; - constructor( - config = { - connectionString: null, - } - ) { - this.connectionString = config.connectionString; - this._client = null; - this.database_id = this.#parseDatabase(); - } - - #parseDatabase() { - const regex = /Database=([^;]+)/; - const match = this.connectionString.match(regex); - return match ? match[1] : null; - } - - async connect() { - this._client = await odbc.connect(this.connectionString); - this.#connected = true; - return this._client; - } - - /** - * - * @param {string} queryString the SQL query to be run - * @returns {import(".").QueryResult} - */ - async runQuery(queryString = "") { - const result = { rows: [], count: 0, error: null }; - try { - if (!this.#connected) await this.connect(); - const query = await this._client.query(queryString); - result.rows = query; - result.count = query.length; - } catch (err) { - console.log(this.constructor.name, err); - result.error = err.message; - } finally { - await this._client.close(); - this.#connected = false; - } - return result; - } - - getTablesSql() { - return `SELECT table_name FROM information_schema.tables WHERE table_schema = '${this.database_id}'`; - } - - getTableSchemaSql(table_name) { - return `SHOW COLUMNS FROM ${this.database_id}.${table_name};`; - } -} - -module.exports.ODBCConnector = ODBCConnector; diff --git a/server/utils/agents/aibitat/plugins/sql-agent/SQLConnectors/index.js b/server/utils/agents/aibitat/plugins/sql-agent/SQLConnectors/index.js index 2e153b7e7..9cf1e1ff4 100644 --- a/server/utils/agents/aibitat/plugins/sql-agent/SQLConnectors/index.js +++ b/server/utils/agents/aibitat/plugins/sql-agent/SQLConnectors/index.js @@ -2,7 +2,7 @@ const { SystemSettings } = require("../../../../../../models/systemSettings"); const { safeJsonParse } = require("../../../../../http"); /** - * @typedef {('postgresql'|'mysql'|'sql-server'|'odbc')} SQLEngine + * @typedef {('postgresql'|'mysql'|'sql-server')} SQLEngine */ /** @@ -36,9 +36,6 @@ function getDBClient(identifier = "", connectionConfig = {}) { case "sql-server": const { MSSQLConnector } = require("./MSSQL"); return new MSSQLConnector(connectionConfig); - case "odbc": - const { ODBCConnector } = require("./ODBC"); - return new ODBCConnector(connectionConfig); default: throw new Error( `There is no supported database connector for ${identifier}` diff --git a/server/yarn.lock b/server/yarn.lock index 8369d829c..fee7c79c8 100644 --- a/server/yarn.lock +++ b/server/yarn.lock @@ -1249,7 +1249,7 @@ "@langchain/core" "~0.1" js-tiktoken "^1.0.11" -"@mapbox/node-pre-gyp@^1.0.11", "@mapbox/node-pre-gyp@^1.0.5": +"@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== @@ -2599,7 +2599,7 @@ arrify@^2.0.0: resolved "https://registry.yarnpkg.com/arrify/-/arrify-2.0.1.tgz#c9655e9331e0abcd588d2a7cad7e9956f66701fa" integrity sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug== -async@^3.0.1, async@^3.2.3, async@^3.2.4: +async@^3.2.3, async@^3.2.4: version "3.2.5" resolved "https://registry.yarnpkg.com/async/-/async-3.2.5.tgz#ebd52a8fdaf7a2289a24df399f8d8485c8a46b66" integrity sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg== @@ -5854,11 +5854,6 @@ node-abort-controller@^3.1.1: resolved "https://registry.yarnpkg.com/node-abort-controller/-/node-abort-controller-3.1.1.tgz#a94377e964a9a37ac3976d848cb5c765833b8548" integrity sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ== -node-addon-api@^3.0.2: - version "3.2.1" - resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-3.2.1.tgz#81325e0a2117789c0128dab65e7e38f07ceba161" - integrity sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A== - node-addon-api@^5.0.0: version "5.1.0" resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-5.1.0.tgz#49da1ca055e109a23d537e9de43c09cca21eb762" @@ -6111,15 +6106,6 @@ octokit@^3.1.0: "@octokit/request-error" "^5.0.0" "@octokit/types" "^12.0.0" -odbc@^2.4.8: - version "2.4.8" - resolved "https://registry.yarnpkg.com/odbc/-/odbc-2.4.8.tgz#56e34a1cafbaf1c2c53eec229b3a7604f890e3bf" - integrity sha512-W4VkBcr8iSe8hqpp2GoFPybCAJefC7eK837XThJkYCW4tBzyQisqkciwt1UYidU1OpKy1589y9dMN0tStiVB1Q== - dependencies: - "@mapbox/node-pre-gyp" "^1.0.5" - async "^3.0.1" - node-addon-api "^3.0.2" - ollama@^0.5.0: version "0.5.0" resolved "https://registry.yarnpkg.com/ollama/-/ollama-0.5.0.tgz#cb9bc709d4d3278c9f484f751b0d9b98b06f4859"