Agent Memory

This page presents the concrete Oracle AI Agent Memory implementation.

Oracle Agent Memory

Note: OracleAgentMemory.delete_thread() is the supported path for thread-scoped cascading cleanup. It removes the thread together with associated messages, durable memories, and managed retrieval data. This is broader than OracleThread.delete_message(), which deletes only the raw message row. Before deleting the thread, it waits for earlier accepted background extraction already known to this client for that thread. It does not serialize every concurrent operation for the same thread while deletion is in progress.

class oracleagentmemory.core.OracleAgentMemory

Bases: IAgentMemory

Agent-memory client backed by Oracle DB or a caller-provided store.

Create a memory client.

Warning: SchemaPolicy.CREATE_IF_NECESSARY can be more expensive than normal client startup because it may apply managed schema DDL and best-effort data rewrites before initialization succeeds. Plan the first open of an older managed schema as a migration or maintenance operation when that schema may contain many rows.

If schema setup must create the managed expired-record purge job but the database user lacks the scheduler-job privilege, initialization warns and continues. Expired messages and memories stay hidden from reads and search, but they are not physically purged until the job is created by a user with CREATE JOB or an equivalent scheduler privilege.

When SchemaPolicy.CREATE_IF_NECESSARY first creates a managed hybrid index over an existing schema, Oracle scans the stored search text and builds the managed hybrid-index state from the configured in-database model. Client startup waits for that DDL to finish, so plan the first hybrid upgrade as a migration or maintenance operation for large schemas. SearchIndexSyncMode controls ongoing maintenance after the index exists; it does not make the first index build asynchronous.

Examples

from oracleagentmemory.core import (
    MemoryExtractionConfig,
    SearchIndexSyncMode,
    OracleAgentMemory,
    SchemaPolicy,
    SearchStrategy,
)
client = OracleAgentMemory(
    connection=db_pool,
    embedder=embedder,
    llm=llm,
)
read_only_client = OracleAgentMemory(
    connection=db_pool,
    embedder=embedder,
    memory_extraction_config=MemoryExtractionConfig(extract_memories=False),
)

Use an in-DB embedding model to exploit Oracle hybrid index search:

from oracleagentmemory.core.embedders import OracleDBEmbedder
db_embedder = OracleDBEmbedder(
    connection=db_pool,
    model="DOC_MODEL",
    embedding_dimension=768,
)
hybrid_client = OracleAgentMemory(
    connection=db_pool,
    embedder=db_embedder,
    schema_policy=SchemaPolicy.CREATE_IF_NECESSARY,
    search_strategy=SearchStrategy.HYBRID,
    search_index_sync=SearchIndexSyncMode.ON_COMMIT,
)

method add_agent

Add an agent profile record to the store.

Notes

Agent profile records are stored in the client-level store and are intentionally unscoped. The returned record identifier is the same public identifier the application uses as agent_id.

Examples

from oracleagentmemory.core import OracleAgentMemory
client = OracleAgentMemory(
    connection=db_pool,
    embedder=embedder,
    llm=llm,
)
client.add_agent(
    "a1",
    "Support assistant",
    metadata={"source": "catalog"},
)
'a1'

method add_memory

Add a memory in the memory system, attributed to the indicated user, agent and thread.

Examples

from oracleagentmemory.core import OracleAgentMemory
client = OracleAgentMemory(
    connection=db_pool,
    embedder=embedder,
    llm=llm,
)
memory_id = client.add_memory("User likes pizza", memory_id="mem-1")
memory_id
'mem-1'

method add_memory_async (async)

Asynchronously add a memory record to the client.

method add_user

Add a user profile record to the store.

Notes

User profile records are stored in the client-level store and are intentionally unscoped. The returned record identifier is the same public identifier the application uses as user_id.

Examples

from oracleagentmemory.core import OracleAgentMemory
client = OracleAgentMemory(
    connection=db_pool,
    embedder=embedder,
    llm=llm,
)
client.add_user(
    "u1",
    "Prefers concise answers.",
    metadata={"source": "crm"},
)
'u1'

method close

Close the agent memory component.

Closing stops accepting new background extraction work and waits for pending background memory extraction to finish up to the configured timeout. If that timeout expires, close() returns even if some background extraction work is still unfinished. The method is idempotent.

Examples

client = OracleAgentMemory(
    connection=db_pool,
    embedder=embedder,
    schema_policy=SchemaPolicy.CREATE_IF_NECESSARY,
    memory_extraction_config=MemoryExtractionConfig(extract_memories=False),
)
client.close()

method close_async (async)

Asynchronously close the agent memory component.

This method follows the same shutdown behavior as close(). If the timeout expires, it can return while background extraction work is still running.

Examples

await client.close_async()

method create_thread

Create and register a thread.

Examples

from oracleagentmemory.core import OracleAgentMemory
client = OracleAgentMemory(
    connection=db_pool,
    embedder=embedder,
    llm=llm,
)
thread = client.create_thread(thread_id="c1", user_id="u1")
thread.thread_id
'c1'

method delete_agent

Delete an agent profile record by identifier.

Notes

Cascading deletes are planned and executed inside the backing store so the profile delete and all scoped child deletes happen in one store operation. Before the cascade delete runs, this method waits for earlier background extraction already accepted for the owned threads known at that time through this agent memory component. It does not wait for work accepted after that wait begins or for work started by another agent memory component or process. Concurrent actor-scoped use while deletion is in progress is unsupported.

Examples

from oracleagentmemory.core import OracleAgentMemory
client = OracleAgentMemory(
    connection=db_pool,
    embedder=embedder,
    llm=llm,
)
client.add_agent("a-delete", "Support assistant")
'a-delete'
client.delete_agent("a-delete")
1

method delete_memory

Delete a memory-like record (e.g., a memory, fact, preference, or guideline) by identifier.

Examples

client = OracleAgentMemory(
    connection=db_pool,
    embedder=embedder,
    llm=llm,
)
memory_id = client.add_memory("Temporary memory", memory_id="mem-delete")
client.delete_memory(memory_id)
1

method delete_memory_async (async)

Asynchronously delete a memory-like record (e.g., a memory, fact, preference, or guideline) by identifier.

method delete_thread

Delete all records associated with a thread identifier.

Notes

Use this operation when you need retention-complete removal of a thread. The backing store deletes the thread together with associated thread-scoped messages, durable memories, and managed retrieval data. This differs from OracleThread.delete_message(), which removes only the raw message record and does not cascade to derived memories created from that message. Before deleting the thread, this method waits for earlier background extraction already accepted for that thread through this agent memory component. It does not wait for background work accepted after that wait begins or for work started by another agent memory component or process. Concurrent use of the same thread while deletion is in progress is unsupported.

Examples

from oracleagentmemory.core import OracleAgentMemory
client = OracleAgentMemory(
    connection=db_pool,
    embedder=embedder,
    llm=llm,
)
thread = client.create_thread(thread_id="c-delete")
client.delete_thread(thread.thread_id)
1

method delete_user

Delete a user profile record by identifier.

Notes

Cascading deletes are planned and executed inside the backing store so the profile delete and all scoped child deletes happen in one store operation. Before the cascade delete runs, this method waits for earlier background extraction already accepted for the owned threads known at that time through this agent memory component. It does not wait for work accepted after that wait begins or for work started by another agent memory component or process. Concurrent actor-scoped use while deletion is in progress is unsupported.

Examples

from oracleagentmemory.core import OracleAgentMemory
client = OracleAgentMemory(
    connection=db_pool,
    embedder=embedder,
    llm=llm,
)
client.add_user("u-delete", "Prefers concise answers.")
'u-delete'
client.delete_user("u-delete")
1

method get_thread

Retrieve a previously created thread.

Notes

Explicit per-call overrides take precedence. When runtime overrides are omitted, reopened threads use persisted runtime config when available before falling back to SDK defaults.

Examples

from oracleagentmemory.core import OracleAgentMemory
client = OracleAgentMemory(
    connection=db_pool,
    embedder=embedder,
    llm=llm,
)
created = client.create_thread(thread_id="c1", user_id="u1")
loaded = client.get_thread("c1")
loaded.user_id
'u1'

Search synchronously for records relevant to a query.

Notes

Explicit None scope values still follow the resolved exact-match rules: exact_*_match=False leaves that dimension unconstrained, while exact_*_match=True matches only records unscoped on that dimension.

method search_async (async)

Search asynchronously for records relevant to a query.

Notes

Explicit None scope values still follow the resolved exact-match rules: exact_*_match=False leaves that dimension unconstrained, while exact_*_match=True matches only records unscoped on that dimension.

method update_memory

Update a stored memory-like record by identifier.

Notes

Omitted fields are preserved from the stored record. Stored scope remains unchanged. Metadata replacement is whole-object replacement, not recursive JSON merge.

method update_memory_async (async)

Asynchronously update a stored memory-like record by identifier.

Notes

Omitted fields remain unchanged. Scope updates are not supported by this API. Metadata replacement is whole-object replacement, not recursive JSON merge.

method update_thread

Persist thread metadata and durable runtime configuration updates.

Notes

Runtime configuration is resolved from the stored conversation thread plus the explicit overrides passed to this call, matching get_thread semantics before persisting the result. Omitted metadata and runtime config updates are resolved from stored data, not from any previously loaded OracleThread instance, and only explicitly provided metadata updates or durable runtime-config overrides are written back. Metadata replacement is whole-object replacement, not recursive JSON merge. Thread ownership is not mutable through this API, so user_id and agent_id remain unchanged. Mutable runtime state, such as extraction counters, is left untouched.

Examples

from oracleagentmemory.core import OracleAgentMemory
client = OracleAgentMemory(
    connection=db_pool,
    embedder=embedder,
    llm=llm,
)
updated = client.update_thread(
    "c1",
    metadata={"flags": {"vip": True}},
    message_shortening_input_token_limit=12_000,
)
updated.message_shortening_input_token_limit
12000

method wait_for_memory_extraction

Wait for earlier background memory extraction started by this client.

This method waits for background extraction already started through this OracleAgentMemory instance, across all threads owned by this agent memory component. It does not wait for extraction started after this wait begins, for extraction started by another agent memory component, or for extraction running in another process. Extraction failures count as finished for this wait.

Examples

client = OracleAgentMemory(
    connection=db_pool,
    embedder=embedder,
    memory_extraction_config=MemoryExtractionConfig(extract_memories=False),
)
client.wait_for_memory_extraction(timeout=10)

method wait_for_memory_extraction_async (async)

Asynchronously wait for earlier background memory extraction.

This method follows the same behavior as wait_for_memory_extraction().

Examples

await client.wait_for_memory_extraction_async(timeout=10)

Memory Extraction

class oracleagentmemory.core.MemoryExtractionConfig

Bases: object

Grouped settings for automatic memory extraction.

Pass this object to OracleAgentMemory, create_thread, get_thread, or update_thread to configure automatic extraction. Omitted fields inherit from the next broader setting. For example, a thread created without memory_extraction_frequency uses the agent memory component default, and the component default falls back to the SDK default.

Examples

from oracleagentmemory.core import MemoryExtractionConfig, MemoryExtractionMode
config = MemoryExtractionConfig(
    extract_memories=True,
    extraction_mode=MemoryExtractionMode.BACKGROUND,
)

class oracleagentmemory.core.MemoryExtractionMode

Bases: str, Enum

Controls when automatic memory extraction work runs.

INLINE runs automatic extraction before the write method returns. BACKGROUND returns after the raw write succeeds and due extraction work is attempted in the background. Background extraction is best effort: derived memories may appear later, or may never be written if the background work cannot complete.

BACKGROUND = ‘BACKGROUND’

Return after raw message persistence and run best-effort extraction in background work.

INLINE = ‘INLINE’

Run extraction before the write method returns.

class oracleagentmemory.core.BackgroundExtractionQueueFullBehavior

Bases: str, Enum

Controls what happens when background extraction cannot queue in time.

DROP = ‘DROP’

Log a warning and continue immediately when queue capacity is unavailable.

WAIT_THEN_DROP = ‘WAIT_THEN_DROP’

Wait for queue capacity up to the configured timeout, then log a warning and continue.

WAIT_THEN_RAISE = ‘WAIT_THEN_RAISE’

Wait for queue capacity up to the configured timeout, then raise TimeoutError.