Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
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
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,8 @@ _These are apps that are not maintained by Mintplex Labs, but are compatible wit
- [Midori AI Subsystem Manager](https://io.midori-ai.xyz/subsystem/anythingllm/) - A streamlined and efficient way to deploy AI systems using Docker container technology.
- [Coolify](https://coolify.io/docs/services/anythingllm/) - Deploy AnythingLLM with a single click.
- [GPTLocalhost for Microsoft Word](https://gptlocalhost.com/demo/) - A local Word Add-in for you to use AnythingLLM in Microsoft Word.
## ✨ Added Features
- **Oracle Database support** for the SQL Agent. See [Oracle Integration](extras/oracle-support.md) for details.

## Telemetry & Privacy

Expand Down
21 changes: 21 additions & 0 deletions extras/build.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
docker build -t anythingllm:orathin -f docker/Dockerfile .

# 1️⃣ Set the storage location to E:\anythingllm
$env:STORAGE_LOCATION="E:\anythingllm"

# 2️⃣ Create the directory if it doesn't exist
If (!(Test-Path $env:STORAGE_LOCATION)) {
New-Item $env:STORAGE_LOCATION -ItemType Directory
}

# 3️⃣ Create the .env file if missing
If (!(Test-Path "$env:STORAGE_LOCATION\.env")) {
New-Item "$env:STORAGE_LOCATION\.env" -ItemType File
}

docker run -d --name anythingllm -p 3001:3001 --network ai_net --cap-add SYS_ADMIN -v "$($env:STORAGE_LOCATION):/app/server/storage" -v "$($env:STORAGE_LOCATION)\.env:/app/server/.env" -e STORAGE_DIR="/app/server/storage" anythingllm:oracle


docker run -d --name chromadb -p 8000:8000 --network anythingllm-net -v "$($env:STORAGE_LOCATION):/chroma/chroma" chromadb/chroma

docker load -i image_filename.tar
260 changes: 260 additions & 0 deletions extras/oracle-support.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,260 @@
# Oracle Database Support Integration -- AnythingLLM (Docker

## Overview

This document summarizes the complete implementation required to add
\*\*Oracle Database support\*\* to AnythingLLM's SQL Agent using the
existing class-based connector architecture located at:
server/utils/agents/aibitat/plugins/sql-agent/SQLConnectors/
The implementation follows the same design pattern used by:

- MySQLConnector
- PostgresSQLConnector
- MSSQLConnector
\
Oracle is integrated as a first-class SQL engine without modifying the
core SQL Agent logic.\
\
\-\--\
\

## Objective

\
Enable SQL Agent support for the following connection format:
oracle://username:password@host:1521/SERVICENAME
Using:

- \`oracledb\` (Thin mode)
- Class-based connector pattern
- Existing \`ConnectionStringParser
- Existing validation and execution flow

## 1. Frontend Modifications

### 1.1 Add Oracle to Engine Enum

\*\*File:\*\*
frontend/src/models/system.js
Update engine type:\
\`\`\`js\
(\'postgresql\'\|\'mysql\'\|\'sql-server\')
To:
(\'postgresql\'\|\'mysql\'\|\'sql-server\'\|\'oracle\')

**1.2 Add Oracle to SQL Engine Selector UI**

**Files Modified:**

- frontend/src/pages/Admin/Agents/SQLConnectorSelection/SQLConnectionModal.jsx
- frontend/src/pages/Admin/Agents/SQLConnectorSelection/DBConnection.jsx
Add:
\<DBEngine provider=\"oracle\" \... /\>
Also include Oracle icon:
frontend/src/pages/Admin/Agents/SQLConnectorSelection/icons/oracle.png
**1.3 Update Connection String Builder**
Ensure the generated format is:
oracle://user:password@host:1521/SERVICENAME
Where:
- SERVICENAME = Oracle Service Name
- Do not use SID unless custom connectString handling is implemented

## 2. Backend Integration

**2.1 Update SQL Engine Typedef**
**File:**
server/utils/agents/aibitat/plugins/sql-agent/SQLConnectors/index.js
Update:
\@typedef {(\'postgresql\'\|\'mysql\'\|\'sql-server\')} SQLEngine

To:
\@typedef {(\'postgresql\'\|\'mysql\'\|\'sql-server\'\|\'oracle\')}
SQLEngine

**2.2 Create Oracle Connector**
**File Created:**
server/utils/agents/aibitat/plugins/sql-agent/SQLConnectors/Oracle.js
**Required Class Structure**
class OracleConnector {\
constructor({ connectionString })\
async runQuery(queryString)\
async validateConnection()\
getTablesSql()\
getTableSchemaSql(table_name)\
}
The class must follow the same structural contract as:

- MySQLConnector
- PostgresSQLConnector
- MSSQLConnector

**2.3 Use ConnectionStringParser**
const parser = new ConnectionStringParser({ scheme: \"oracle\" });
Important:\
The scheme must match the frontend engine name exactly.

**2.4 Validation Query**
Oracle requires:
SELECT 1 FROM DUAL;
Not:
SELECT 1;

**2.5 Table Metadata Queries**
**List Tables**

SELECT table_name FROM user_tables;
**Get Table Schema**

SELECT column_name, data_type\
FROM user_tab_columns\
WHERE table_name = UPPER(\'TABLE_NAME\');

**2.6 Register Oracle Connector**

**File:**
server/utils/agents/aibitat/plugins/sql-agent/SQLConnectors/index.js
Inside getDBClient():
case \"oracle\":\
const { OracleConnector } = require(\"./Oracle\");\
return new OracleConnector(connectionConfig);

**3. Install Oracle Driver**
Inside:
server/
Install:
npm install oracledb
Or add to server/package.json:
\"oracledb\": \"\^6.0.0\"

**4. Docker Considerations**
Running inside Docker requires **no Oracle Instant Client**.
Not required:

- Oracle Instant Client
- Native libraries
- LD_LIBRARY_PATH
- initOracleClient()

Reason:

- oracledb defaults to Thin mode
- Thin mode uses pure TCP
- Compatible with Node Alpine images
Rebuild image:
docker build -t anythingllm-custom .
Modified Docker file:
docker/dockerfile

**5. Execution Flow After Integration**
**Connection Validation**
Frontend\
↓\
POST /system/validate-sql-connection\
↓\
validateConnection()\
↓\
getDBClient(\"oracle\")\
↓\
new OracleConnector()\
↓\
validateConnection()

**Agent Query Execution**
Agent\
↓\
getDBClient()\
↓\
connector.runQuery()

No core SQL Agent logic modifications are required.

**6. Oracle vs MySQL Differences**

---

**MySQL** **Oracle**

---

SELECT 1 SELECT 1 FROM DUAL

information_schema user_tables

SHOW COLUMNS user_tab_columns

.end() .close()

? binds :1 binds

Database name Service name

---

All database-specific behavior is encapsulated inside OracleConnector.

**7. Architectural Outcome**

After implementation:

- Oracle becomes a first-class SQL engine
- Polymorphism is preserved
- SQL Agent remains database-agnostic
- No conditional hacks in core logic
- Fully aligned with project design

**8. Maintenance Note**

This implementation creates a custom fork.

Future upstream updates may require manual merging of:

- SQLConnectors/index.js

- SQLConnectors/

- Frontend engine enum changes

**9. Complete File Changes**

**Frontend**

1. frontend/src/pages/Admin/Agents/SQLConnectorSelection/icons/oracle.png

2. frontend/src/models/system.js

3. frontend/src/pages/Admin/Agents/SQLConnectorSelection/DBConnection.jsx

4. frontend/src/pages/Admin/Agents/SQLConnectorSelection/SQLConnectionModal.jsx

**Backend**

5. server/utils/agents/aibitat/plugins/sql-agent/SQLConnector/utils.js

6. server/utils/agents/aibitat/plugins/sql-agent/SQLConnectors/Oracle.js

7. server/utils/agents/aibitat/plugins/sql-agent/SQLConnectors/index.js

8. server/package.json
9. build.txt (Build Guide)
10. oracle-support.md (Support Document)

**Docker**

9. docker/dockerfile

**Final Minimal Checklist**

1. Add Oracle to frontend engine list

2. Create OracleConnector class

3. Register in getDBClient()

4. Install oracledb

5. Rebuild Docker image

6. Test with SELECT 1 FROM DUAL

Oracle support is now fully integrated using the native connector
architecture with no impact on existing SQL engines.
4 changes: 2 additions & 2 deletions frontend/src/models/system.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ const System = {
.catch(() => 0);
},

/**
/***
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/** opens JS multi-line comment, no need for an extra!

* Checks if the onboarding is complete.
* @returns {Promise<boolean>}
*/
Expand Down Expand Up @@ -849,7 +849,7 @@ const System = {

/**
* Validates a SQL connection string.
* @param {'postgresql'|'mysql'|'sql-server'} engine - the database engine identifier
* @param {'postgresql'|'mysql'|'sql-server'|'oracle'} engine - the database engine identifier
* @param {string} connectionString - the connection string to validate
* @returns {Promise<{success: boolean, error: string | null}>}
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import PostgreSQLLogo from "./icons/postgresql.png";
import MySQLLogo from "./icons/mysql.png";
import MSSQLLogo from "./icons/mssql.png";
import OracleLogo from "./icons/oracle.png";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PNG needs a white bg and be 330x330px if not already

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes are made in the Review PR


import { PencilSimple, X } from "@phosphor-icons/react";
import { useModal } from "@/hooks/useModal";
import EditSQLConnection from "./SQLConnectionModal";
Expand All @@ -9,6 +11,7 @@ export const DB_LOGOS = {
postgresql: PostgreSQLLogo,
mysql: MySQLLogo,
"sql-server": MSSQLLogo,
oracle: OracleLogo,
};

export default function DBConnection({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ function assembleConnectionString({
return `mysql://${username}:${password}@${host}:${port}/${database}`;
case "sql-server":
return `mssql://${username}:${password}@${host}:${port}/${database}?encrypt=${encrypt}`;
case "oracle":
return `oracle://${username}:${password}@${host}:${port}/${database}`;
default:
return null;
}
Expand Down Expand Up @@ -316,6 +318,11 @@ export default function SQLConnectionModal({
active={engine === "sql-server"}
onClick={() => setEngine("sql-server")}
/>
<DBEngine
provider="oracle"
active={engine === "oracle"}
onClick={() => setEngine("oracle")}
/>
</div>
</div>

Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
"mysql2": "^3.9.8",
"ollama": "^0.6.3",
"openai": "4.95.1",
"oracledb": "^6.10.0",
"pg": "^8.11.5",
"pinecone-client": "^1.1.0",
"pluralize": "^8.0.0",
Expand Down
Loading