Skip to content
Open
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
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ For enterprise deployment and custom solutions, contact **info@nevamind.ai**
pip install -e .
```


#### Basic Example

> **Requirements**: Python 3.13+ and an OpenAI API key
Expand Down
43 changes: 43 additions & 0 deletions docs/oracle_integration.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Oracle Database Integration

## Installation

To use the Oracle Database integration, you must have the `oracledb` python driver installed.

```bash
```bash
uv add memu-py[oracle]
# or
uv add memu-py --optional oracle
```

## Configuration

The connection URI must use the `oracle+oracledb` prefix.

### Format
`oracle+oracledb://<username>:<password>@<host>:<port>/?service_name=<service_name>`

### Example

```python
config = {
"metadata_store": {
"dsn": "oracle+oracledb://myuser:mypassword@localhost:1521/?service_name=XE",
"ddl_mode": "create"
}
}
```

The system will automatically convert `oracle://` to `oracle+oracledb://` if the simplified prefix is used, but it is recommended to use the full driver prefix.

## Testing

> [!IMPORTANT]
> The integration includes a robust mock test suite that allows validation of the logic without requiring a local Oracle instance.

You can run the unit tests using `pytest`:

```bash
uv run pytest tests/test_oracle_mock.py
```
42 changes: 42 additions & 0 deletions docs/oracle_provider.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Oracle Database Provider

MemU supports Oracle Database as a backend for storing memories.

## Installation

To enable the Oracle provider, you must install the `oracledb` dependency.

```bash
uv add oracledb
```

## Configuration

You can configure the Oracle repository by instantiating it with your credentials:

```python
from memu.database.oracle import OracleMemoryItemRepo

# Using explicit credentials and DSN
repo = OracleMemoryItemRepo(
user="myuser",
password="mypassword",
dsn="localhost:1521/XEPDB1"
)

# Using wallet or other connection methods supported by python-oracledb
# For thick mode (required for some advanced features), ensure Instant Client is installed
# and initialized before creating the repo.
import oracledb
# oracledb.init_oracle_client(lib_dir="/path/to/instantclient")
```

## Features

- **Storage**: Full support for `MemoryItem`, `MemoryCategory`, and `CategoryItem`.
- **Embeddings**: Stored as JSON CLOBs (Vector type support pending).
- **Strict Typing**: Fully typed and compliant with MemU protocols.

## Limitations

- **Vector Search**: Currently raises `NotImplementedError`. Implementation requires Oracle Database 23ai or newer with Vector support enabled, or a custom PL/SQL implementation which is not currently included.
7 changes: 7 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ test = [

[project.optional-dependencies]
postgres = ["pgvector>=0.3.4", "sqlalchemy[postgresql-psycopgbinary]>=2.0.36"]
oracle = [
"oracledb>=3.4.1",
]

[project.urls]
"Homepage" = "https://github.com/NevaMind-AI/MemU"
Expand Down Expand Up @@ -95,6 +98,10 @@ disable_error_code = ["attr-defined", "call-arg"]
module = ["pgvector.*"]
ignore_missing_imports = true

[[tool.mypy.overrides]]
module = ["oracledb"]
ignore_missing_imports = true

[tool.ruff]
target-version = "py313"
line-length = 120
Expand Down
4 changes: 3 additions & 1 deletion src/memu/app/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
UserConfig,
)
from memu.blob.local_fs import LocalFS
from memu.database.factory import build_database
from memu.database.interfaces import Database
from memu.llm.http_client import HTTPLLMClient
from memu.llm.wrapper import (
Expand Down Expand Up @@ -74,10 +73,13 @@ def __init__(

self._context = Context(categories_ready=not bool(self.category_configs))

from memu.database.factory import build_database

self.database: Database = build_database(
config=self.database_config,
user_model=self.user_model,
)

# We need the concrete user scope (user_id: xxx) to initialize the categories
# self._start_category_initialization(self._context, self.database)

Expand Down
5 changes: 5 additions & 0 deletions src/memu/database/factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ def build_database(
from memu.database.sqlite import build_sqlite_database

return build_sqlite_database(config=config, user_model=user_model)
elif provider == "oracle":
# Lazy import to avoid loading Oracle dependencies when not needed
from memu.database.oracle.oracle import build_oracle_database

return build_oracle_database(config=config, user_model=user_model)
else:
msg = f"Unsupported metadata_store provider: {provider}"
raise ValueError(msg)
13 changes: 13 additions & 0 deletions src/memu/database/oracle/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from memu.database.oracle.oracle import (
OracleCategoryItemRepo,
OracleMemoryCategoryRepo,
OracleMemoryItemRepo,
build_oracle_database,
)

__all__ = [
"OracleCategoryItemRepo",
"OracleMemoryCategoryRepo",
"OracleMemoryItemRepo",
"build_oracle_database",
]
Loading