Stores and Schema
This page presents the core store abstractions and schema controls used by the Oracle Agent Memory SDK.
Store API
Store Write Semantics
Store writes keep a clear separation between the text an application stores and
the payload the store uses for retrieval. Most applications can use the
memory-level and thread-level APIs and let the store prepare the search rows it
needs for vector, keyword, or hybrid retrieval. The lower-level store APIs
expose index_texts, index_text, embeddings, and embedding for
advanced integrations that already know what text or vectors should be used for retrieval.
Think of each write as two related pieces:
contentsinadd()andcontentinupdate()control the stored record content returned byget(),list(), and search results.index_textsinadd()andindex_textinupdate()control the text written to the store’s retrieval rows. Search uses those rows, then returns the original logical records.
update() also accepts text as a deprecated compatibility parameter.
Use content in new code; supplying text emits a deprecation warning.
If no search override or explicit embedding is provided, the store uses the resolved stored text as the retrieval text. Non-empty text is chunked by the store when chunking is configured. Empty text stores the record text but provides no retrieval text.
The table below describes how retrieval text is chosen before explicit vector payloads are considered.
Store-level retrieval payloads
| Input | add() |
update() |
|---|---|---|
index_texts or index_text omitted |
Each record uses its resolved contents value for retrieval. |
A replacement content value is used for retrieval. If content is also omitted, embedding-only updates reuse the record’s existing retrieval text rows. |
String index_texts entry or string index_text |
The string replaces the retrieval text for that record. The store may chunk it before writing retrieval rows. | The string replaces the retrieval text for that record. The store may chunk it before writing retrieval rows. |
list[str] index_texts entry or list[str] index_text |
The list is treated as caller-owned chunks. Each non-empty string is written as one retrieval row, and the store does not chunk it again. | The list is treated as caller-owned chunks. Each non-empty string is written as one retrieval row, and the store does not chunk it again. |
None index_texts entry or index_text=None |
None in the outer index_texts list means “use the stored content for this record.” |
index_text=None clears the retrieval rows while leaving stored content unchanged unless content is also supplied. |
| Empty string or empty chunk list | Stores the record content and provides no retrieval text for that record. | Updates the record content when content is supplied and clears retrieval text for that record. |
Explicit embeddings are optional. When they are omitted, the store derives
local vectors from the retrieval text when local vector storage is configured;
keyword or hybrid stores may also use text-only retrieval rows. When explicit
embeddings or embedding values are supplied, the store writes those
vectors directly and does not call its embedder for those vectors.
In add(), embeddings=None behaves like omitting embeddings. In
update(), embedding=None is explicit: the store keeps or rewrites the
retrieval text according to content and index_text, but stores those
rows without local vectors. If content and index_text are both
omitted, this clears vectors from the existing retrieval rows.
The vector shape tells the store how much chunk ownership the caller is taking:
- one vector means one vector for the whole retrieval text. The store does not split that text for the explicit vector. If that retrieval text is empty, the vector can be stored without companion chunk text.
- multiple vectors mean one vector per caller-owned chunk. Provide matching
index_textsorindex_textchunk lists, or use an embedding-onlyupdate()that reuses the record’s existing retrieval text rows. - vector counts must match chunk counts, and all explicit vectors in one
add()call must have the same dimension. - an empty per-record vector payload is allowed only when there are no retrieval text rows to align with it.
Some combinations are rejected so stored text, retrieval text, and vectors do
not drift apart. Passing content=None clears stored content and retrieval
rows, so it cannot be combined with non-null index_text or embedding
values; actor profile records do not support content=None. The deprecated
text parameter has the same behavior. Passing index_text=None in
update() means “clear retrieval rows”, so non-empty explicit embeddings
are not allowed in the same call. Multiple explicit vectors require explicit
chunk text, unless the update is embedding-only and the existing retrieval rows
already provide the chunk text.
class oracleagentmemory.core.OracleMemoryStore
Bases: IMemoryStore
Common store interface used by OracleAgentMemory.
A store implementation is responsible for persisting text records and performing similarity search over them. Both synchronous and asynchronous entry points are defined so higher-level APIs can expose matching sync/async surfaces without duplicating store-specific logic.
method add
Add records to the store.
- Parameters:
- contents
Sequence[str | Mapping[str, object] | Sequence[MessageContent] | bytes | None]– Read-only sequence of record payloads. Message entries may contain orderedMessageContentparts, while thread-summary entries may be mappings. Text values are also used for semantic indexing unlessindex_textsorembeddingsare provided. When a text value isNone, implementations may fall back tometadata["content"]. Explicit empty strings are preserved. - record_type
str– Logical record type to create, for example"message","memory","guideline","fact","preference","user_profile","agent_profile", or"thread_summary". - index_texts
list[str | list[str] | None]– Optional alternative payloads used only for semantic indexing. When provided, the outer list must align with the text inputs. Each entry may be a string, which the store may chunk internally, or a list of non-empty strings, which the store treats as caller-owned chunks and must not split again. - embeddings
list[list[float] | ndarray | list[list[float] | ndarray]]– Optional precomputed embedding vectors aligned with the text inputs. Each record entry may be either one embedding vector or a list of chunk embedding vectors for that record. When provided, the store must use these vectors directly instead of invoking its embedder. Multiple vectors for one record require matchingindex_textschunk lists so text and vector chunk boundaries are explicit. If not provided, stores usually derive semantic state from their configured embedder, but implementation-specific text-aware indexing modes may also allow text-only writes without one. - record_ids
str | None | list[str | None]– Optional caller-visible identifiers. A single string may be used for one-record inserts, while lists must align with the text inputs. Generated identifiers are returned when this field is omitted. - thread_ids
str | None | list[str | None]– Optional thread identifiers associated with the inserted records. Scalar values may be broadcast across aligned text inputs. - user_ids
str | None | list[str | None]– Optional user identifiers associated with the inserted records. Scalar values may be broadcast across aligned text inputs. - agent_ids
str | None | list[str | None]– Optional agent identifiers associated with the inserted records. Scalar values may be broadcast across aligned text inputs. - roles
str | None | list[str | None]– Optional message roles such as"user"or"assistant". Scalar values may be broadcast across aligned text inputs. Used only if record_type is"message". - timestamps
str | None | list[str | None]– Optional timestamps to save with the records. Each timestamp represents an event associated with the record. Scalar values may be broadcast across aligned text inputs. Omitted orNoneentries store aNULLevent timestamp; reads use the record creation time as the effective timestamp. - metadata
dict[str, Any] | None | list[dict[str, Any] | None]– Optional caller-provided metadata dictionaries. Metadata may include"content"as fallback source when a text value is omitted rather than explicitly set to"". Whenrecord_type="image", each image write requires"image_mime_type"with one of"image/png","image/jpeg", or"image/webp". The store uses this field to save the image, but does not return it as part of the record’s metadata. - ttl_days
int | None | list[int | None]– Optional time-to-live duration in days for records that support expiration. Omit this argument to use the store default. PassNonefor records that should not expire. Scalar values may be broadcast across aligned text inputs. - ttl_anchor
TimeToLiveAnchor | list[TimeToLiveAnchor]– Optional time-to-live anchor. UseTimeToLiveAnchor.CREATED_ATto expire relative to the stored creation time, orTimeToLiveAnchor.TIMESTAMPto expire relative to each record’s event timestamp. When omitted, implementations useTimeToLiveAnchor.CREATED_AT. - statuses
RecordStatus | list[RecordStatus]– Optional lifecycle status or statuses for records. Omit this to storeRecordStatus.VALID. - **store_kwargs (Any) – Implementation-specific write options forwarded to the concrete store.
- contents
- Return type: list[str]
Notes
Use add_batches() when the caller already has one or more
PendingRecordBatch objects.
- Returns: Identifiers for the inserted records, in the same logical order as the input.
- Return type: List[str]
- Parameters:
- contents
Sequence[str | Mapping[str, object] | Sequence[MessageContent] | bytes | None] - record_type
str - index_texts
list[str | list[str] | None] - embeddings
list[list[float] | ndarray | list[list[float] | ndarray]] - record_ids
str | None | list[str | None] - thread_ids
str | None | list[str | None] - user_ids
str | None | list[str | None] - agent_ids
str | None | list[str | None] - roles
str | None | list[str | None] - timestamps
str | None | list[str | None] - metadata
dict[str, Any] | None | list[dict[str, Any] | None] - ttl_days
int | None | list[int | None] - ttl_anchor
TimeToLiveAnchor | list[TimeToLiveAnchor] - statuses
RecordStatus | list[RecordStatus] - store_kwargs
Any
- contents
method add_agent (abstract)
Add an agent profile record.
- Parameters:
- agent_id
str– Stable identifier for the agent profile. - information
str– Free-form text describing the agent. - metadata
dict[str, Any] | None– Optional metadata mapping stored on the agent profile row.
- agent_id
- Returns: Identifier of the created agent profile record.
- Return type: str
method add_agent_async (async)
Asynchronously add an agent profile record.
- Parameters:
- agent_id
str– Stable identifier for the agent profile. - information
str– Free-form text describing the agent. - metadata
dict[str, Any] | None– Optional metadata mapping stored on the agent profile row.
- agent_id
- Returns: Identifier of the created agent profile record.
- Return type: str
method add_async (async)
Asynchronously add row-oriented records to the store.
Accepts the same arguments and returns the same identifiers as add().
- Parameters:
- contents
Sequence[str | Mapping[str, object] | Sequence[MessageContent] | bytes | None] - record_type
str - index_texts
list[str | list[str] | None] - embeddings
list[list[float] | ndarray | list[list[float] | ndarray]] - record_ids
str | None | list[str | None] - thread_ids
str | None | list[str | None] - user_ids
str | None | list[str | None] - agent_ids
str | None | list[str | None] - roles
str | None | list[str | None] - timestamps
str | None | list[str | None] - metadata
dict[str, Any] | None | list[dict[str, Any] | None] - ttl_days
int | None | list[int | None] - ttl_anchor
TimeToLiveAnchor | list[TimeToLiveAnchor] - statuses
RecordStatus | list[RecordStatus] - store_kwargs
Any
- contents
- Return type: list[str]
method add_batches
Add caller-prepared logical batches to the store.
- Parameters:
- batches
list[PendingRecordBatch]– Fully prepared logical batches to persist. Each batch should carry its own per-record fields such asrecord_type, scope values, roles, timestamps, and metadata. - **store_kwargs (Any) – Implementation-specific write options forwarded to the concrete store.
- batches
- Returns: Identifiers for the inserted records, in the same logical order as the input batches and rows.
- Return type: List[str]
Examples
store.add_batches(
[
PendingRecordBatch(
contents=["pizza batch"],
record_type="memory",
record_ids="mem-batch-docs",
)
]
)
['mem-batch-docs']
method add_batches_async (async)
Asynchronously add caller-prepared logical batches to the store.
Accepts the same arguments and returns the same identifiers as
add_batches().
- Parameters:
- batches
list[PendingRecordBatch] - store_kwargs
Any
- batches
- Return type: list[str]
method add_relations (abstract)
Store one or more directed relations.
Scalar values are broadcast across the source-record batch. List
values must have the same length. Only one orientation can be stored
for an endpoint pair. Use opposite_relation_types to describe the
reverse view rather than adding a second reverse relation.
Implementations may restrict which endpoint record types and relation
labels they persist.
- Parameters:
- source_record_ids
str | list[str]– Identifier or identifiers of records at the source end of each directed relation. - source_record_types
str | list[str]– Record type or types forsource_record_ids. Supply one value for all sources or one value for each relation. - target_record_ids
str | list[str]– Identifier or identifiers of records at the target end of each directed relation. - target_record_types
str | list[str]– Record type or types fortarget_record_ids. Supply one value for all targets or one value for each relation. - relation_types
str | list[str]– Directed relation label or labels. Supply one value for all relations or one value for each relation. - opposite_relation_types
str | list[str]– Optional label or labels for the reverse view of each relation. For built-in memory relation types, omission uses the predefined reverse label. For custom relation types, omission uses the same label in both directions. - relation_ids
str | None | list[str | None]– Optional stable identifier or identifiers. Omit this to let the store generate identifiers. - timestamps
str | None | list[str | None]– Optional timestamp or timestamps to store on the relations. - metadata
dict[str, Any] | None | list[dict[str, Any] | None]– Optional metadata object or objects to store on the relations.
- source_record_ids
- Returns: Relation identifiers in input order.
- Return type: list[str]
Examples
store.add_relations(
"new", "memory", "old", "memory", "supersedes"
)
['relation-id']
method add_relations_async (async)
Asynchronously store one or more directed relations.
Scalar values are broadcast across the source-record batch. List
values must have the same length. Only one orientation can be stored
for an endpoint pair. Use opposite_relation_types to describe the
reverse view rather than adding a second reverse relation.
- Parameters:
- source_record_ids
str | list[str]– Identifier or identifiers of records at the source end of each directed relation. - source_record_types
str | list[str]– Record type or types forsource_record_ids. Supply one value for all sources or one value for each relation. - target_record_ids
str | list[str]– Identifier or identifiers of records at the target end of each directed relation. - target_record_types
str | list[str]– Record type or types fortarget_record_ids. Supply one value for all targets or one value for each relation. - relation_types
str | list[str]– Directed relation label or labels. Supply one value for all relations or one value for each relation. - opposite_relation_types
str | list[str]– Optional label or labels for the reverse view of each relation. For built-in memory relation types, omission uses the predefined reverse label. For custom relation types, omission uses the same label in both directions. - relation_ids
str | None | list[str | None]– Optional stable identifier or identifiers. Omit this to let the store generate identifiers. - timestamps
str | None | list[str | None]– Optional timestamp or timestamps to store on the relations. - metadata
dict[str, Any] | None | list[dict[str, Any] | None]– Optional metadata object or objects to store on the relations.
- source_record_ids
- Returns: Relation identifiers in input order.
- Return type: list[str]
Examples
await store.add_relations_async(
"new", "memory", "old", "memory", "supersedes"
)
['relation-id']
method add_user (abstract)
Add a user profile record.
- Parameters:
- user_id
str– Stable identifier for the user profile. DB-backed implementations may infer this value from an attached end-user security context when it is omitted. - information
str– Required free-form text describing the user. - metadata
dict[str, Any] | None– Optional metadata mapping stored on the user profile row.
- user_id
- Returns: Identifier of the created user profile record.
- Return type: str
method add_user_async (async)
Asynchronously add a user profile record.
- Parameters:
- user_id
str– Stable identifier for the user profile. - information
str– Free-form text describing the user. - metadata
dict[str, Any] | None– Optional metadata mapping stored on the user profile row.
- user_id
- Returns: Identifier of the created user profile record.
- Return type: str
method delete (abstract)
Delete one stored record by identifier.
- Parameters:
- record_type
str– Logical type of the record to remove. - record_id
str– Identifier of the record to remove. - cascade
bool– WhenTrue, apply any store-supported cascading delete behavior for the requested top-level targets inside the same delete operation. This is primarily used for targets such as actor profiles that own additional scoped records. For example, a user-profile or agent-profile cascade may delete owned threads themselves, the thread-scoped messages and memory-like records removed with those threads, and any remaining directly actor-scoped records such as messages, memories, guidelines, facts, or preferences. For actor-profile deletes, this scoped cleanup may still run when the matching profile row is already absent.
- record_type
- Returns:
Number of requested top-level records deleted, typically
0or1. Cascaded child rows are not counted separately, so this may still be0when a missing actor profile triggers scoped cleanup. - Return type: int
method delete_async (async)
Asynchronously delete one stored record by identifier.
- Parameters:
- record_type
str– Logical type of the record to remove. - record_id
str– Identifier of the record to remove. - cascade
bool– WhenTrue, apply any store-supported cascading delete behavior for the requested top-level targets inside the same delete operation. This is primarily used for targets such as actor profiles that own additional scoped records. For example, a user-profile or agent-profile cascade may delete owned threads themselves, the thread-scoped messages and memory-like records removed with those threads, and any remaining directly actor-scoped records such as messages, memories, guidelines, facts, or preferences. For actor-profile deletes, this scoped cleanup may still run when the matching profile row is already absent.
- record_type
- Returns:
Number of requested top-level records deleted, typically
0or1. Cascaded child rows are not counted separately, so this may still be0when a missing actor profile triggers scoped cleanup. - Return type: int
method delete_relations (abstract)
Delete relations by identifier.
Lifecycle state is recalculated from the relations that remain.
- Parameters:
relation_ids
str | list[str]– Identifier or identifiers of the relations to delete. - Returns: Number of deleted relations.
- Return type: int
Examples
store.delete_relations("relation-id")
1
method delete_relations_async (async)
Asynchronously delete relations by identifier.
Lifecycle state is recalculated from the relations that remain.
- Parameters:
relation_ids
str | list[str]– Identifier or identifiers of the relations to delete. - Returns: Number of deleted relations.
- Return type: int
Examples
await store.delete_relations_async("relation-id")
1
method delete_thread (abstract)
Delete a thread and its associated stored data.
- Parameters:
thread_id
str– Identifier of the thread to remove. - Returns:
Number of deleted thread records, typically
0or1. - Return type: int
Notes
This is the store-level operation for removing a thread and the thread-scoped records managed by the store. Prefer thread deletion when retention requirements call for deleting both source messages and derived thread-scoped memory data, because message-level deletes do not imply that separately persisted derived records are removed.
method delete_thread_async (async)
Asynchronously delete a thread and its associated stored data.
- Parameters:
thread_id
str– Identifier of the thread to remove. - Returns:
Number of deleted thread records, typically
0or1. - Return type: int
Notes
This is the store-level operation for removing a thread and the thread-scoped records managed by the store. Prefer thread deletion when retention requirements call for deleting both source messages and derived thread-scoped memory data, because message-level deletes do not imply that separately persisted derived records are removed.
method get (abstract)
Retrieve one stored record by type and identifier.
- Parameters:
- record_type
str– Logical type of the record to retrieve, such as"thread","message","memory","guideline","fact","preference","user_profile","agent_profile", or"image". - record_id
str– Identifier of the record to retrieve. - include_bytes
bool– Whether to load stored image bytes. For a message record, this controls whether attached images include their bytes. For an image record, it controls whether the standalone image bytes are loaded. This option has no effect on other record types.
- record_type
- Returns:
The stored record when found, otherwise
None. A"thread"lookup returns aThreadRecordwith thread metadata, runtime configuration, runtime state, and the creation timestamp populated when the store supports persisted threads. - Return type: Record | None
method get_async (async)
Asynchronously retrieve one stored record by type and identifier.
- Parameters:
- record_type
str– Logical type of the record to retrieve, such as"thread","message","memory","guideline","fact","preference","user_profile","agent_profile", or"image". - record_id
str– Identifier of the record to retrieve. - include_bytes
bool– Whether to load stored image bytes. For a message record, this controls whether attached images include their bytes. For an image record, it controls whether the standalone image bytes are loaded. This option has no effect on other record types.
- record_type
- Returns:
The stored record when found, otherwise
None. A"thread"lookup returns aThreadRecordwith thread metadata, runtime configuration, runtime state, and the creation timestamp populated when the store supports persisted threads. - Return type: Record | None
method get_relation (abstract)
Return one relation in its stored source-to-target orientation.
Provide relation_id alone, or provide one complete source-to-target
endpoint tuple.
- Parameters:
- source_record_id
str– Source record identifier. Required with the other endpoint-tuple fields whenrelation_idis omitted. - source_record_type
str– Source record type. Required with the other endpoint-tuple fields whenrelation_idis omitted. - target_record_id
str– Target record identifier. Required with the other endpoint-tuple fields whenrelation_idis omitted. - target_record_type
str– Target record type. Required with the other endpoint-tuple fields whenrelation_idis omitted. - relation_type
str– Directed relation label. Required with the other endpoint-tuple fields whenrelation_idis omitted. - relation_id
str– Relation identifier to match directly. Provide this argument alone rather than combining it with endpoint-tuple fields.
- source_record_id
- Returns:
The matching relation, or
Nonewhen it does not exist. - Return type: RecordRelation | None
Examples
store.get_relation(relation_id="relation-id")
RecordRelation(...)
store.get_relation(
"source-id", "memory", "target-id", "fact", "supports"
)
RecordRelation(...)
method get_relation_async (async)
Asynchronously retrieve one relation by ID or endpoint tuple.
Provide relation_id alone, or provide one complete source-to-target
endpoint tuple.
- Parameters:
- source_record_id
str– Source record identifier. Required with the other endpoint-tuple fields whenrelation_idis omitted. - source_record_type
str– Source record type. Required with the other endpoint-tuple fields whenrelation_idis omitted. - target_record_id
str– Target record identifier. Required with the other endpoint-tuple fields whenrelation_idis omitted. - target_record_type
str– Target record type. Required with the other endpoint-tuple fields whenrelation_idis omitted. - relation_type
str– Directed relation label. Required with the other endpoint-tuple fields whenrelation_idis omitted. - relation_id
str– Relation identifier to match directly. Provide this argument alone rather than combining it with endpoint-tuple fields.
- source_record_id
- Returns:
The matching relation, or
Nonewhen it does not exist. - Return type: RecordRelation | None
Examples
await store.get_relation_async(relation_id="relation-id")
RecordRelation(...)
method list (abstract)
List stored records for one record type.
- Parameters:
- record_type
str– Logical record type to enumerate, such as"thread","message","memory","guideline","fact","preference","user_profile","agent_profile", or"thread_summary"or"image". - limit
int | None– Optional maximum number of most-recent records to return. When omitted, implementations may apply a safe upper bound such asMAX_LIST_LIMIT. PassNoneto disable that cap and return every matching record. - thread_id
str | None– Exact thread-scope filter. When omitted, no filtering is applied. When set toNone, only records whosethread_idisNoneare returned. Unscoped record types ignore this filter. Whenrecord_typeis"thread",thread_idshould not be set; userecord_idto select a specific thread. - user_id
str | None– Exact user-scope filter. When omitted, no filtering is applied. When set toNone, only records whoseuser_idisNoneare returned. Unscoped record types ignore this filter. - agent_id
str | None– Exact agent-scope filter. When omitted, no filtering is applied. When set toNone, only records whoseagent_idisNoneare returned. Unscoped record types ignore this filter. -
metadata_filter
dict[str, Any] | None–Metadata filter. When omitted, no filtering is applied. When set to
None, only records whose metadata isNoneare returned. When set to a dict, entries inmetadata_filterare combined with AND semantics. Entries whose value is not a field-level operator dictionary use exact-match semantics: the requested key must exist in the stored metadata. Nested dictionaries are matched recursively. Scalar and list values are matched by exact equality; list order and length must also match. To test array membership, use a field-level operator dictionary such as{"tags": {"$array_contains": "prod"}}. A list operand for"$array_contains"means all listed values must be present;"$array_contains_any"means at least one listed value must be present. Use"$not"to negate another field-level expression at the same field, including an operator dictionary or raw exact-match value. Negated expressions match when the positive expression would fail, including missing fields; negated array membership also matches non-array fields. Examples includemetadata_filter={"source": "slack"}for a scalar field,metadata_filter={"review": {"status": "open"}}for a nested field, andmetadata_filter={"tags": ["prod", "urgent"]}for an exact list match. Combine conditions to require all of them:metadata_filter={ "source": "slack", "review": {"status": "open"}, "tags": ["prod", "urgent"], } - include_bytes
bool– Whether image records or images attached to message records include their stored bytes. When omitted orFalse, image descriptions and metadata are returned without loading bytes. For direct image listings, set this toTrueonly with an exactrecord_idand at least one exact user, agent, or thread scope filter. This option has no effect on other record types. - record_id
str– Exact record identifier filter. When omitted, records with any identifier are returned. Scope and metadata filters remain additional constraints.
- record_type
- Returns: Records ordered from oldest to newest within the returned window.
- Return type: List[Record]
method list_async (async)
Asynchronously list stored records for one record type.
- Parameters:
- record_type
str– Logical record type to enumerate, such as"thread","message","memory","guideline","fact","preference","user_profile","agent_profile", or"image". - limit
int | None– Optional maximum number of most-recent records to return. When omitted, implementations may apply a safe upper bound such asMAX_LIST_LIMIT. PassNoneto disable that cap and return every matching record. - thread_id
str | None– Exact thread-scope filter. When omitted, no filtering is applied. When set toNone, only records whosethread_idisNoneare returned. Unscoped record types ignore this filter. Whenrecord_typeis"thread",thread_idshould not be set; userecord_idto select a specific thread. - user_id
str | None– Exact user-scope filter. When omitted, no filtering is applied. When set toNone, only records whoseuser_idisNoneare returned. Unscoped record types ignore this filter. - agent_id
str | None– Exact agent-scope filter. When omitted, no filtering is applied. When set toNone, only records whoseagent_idisNoneare returned. Unscoped record types ignore this filter. -
metadata_filter
dict[str, Any] | None–Metadata filter. When omitted, no filtering is applied. When set to
None, only records whose metadata isNoneare returned. When set to a dict, entries inmetadata_filterare combined with AND semantics. Entries whose value is not a field-level operator dictionary use exact-match semantics: the requested key must exist in the stored metadata. Nested dictionaries are matched recursively. Scalar and list values are matched by exact equality; list order and length must also match. To test array membership, use a field-level operator dictionary such as{"tags": {"$array_contains": "prod"}}. A list operand for"$array_contains"means all listed values must be present;"$array_contains_any"means at least one listed value must be present. Use"$not"to negate another field-level expression at the same field, including an operator dictionary or raw exact-match value. Negated expressions match when the positive expression would fail, including missing fields; negated array membership also matches non-array fields. Examples includemetadata_filter={"source": "slack"}for a scalar field,metadata_filter={"review": {"status": "open"}}for a nested field, andmetadata_filter={"tags": ["prod", "urgent"]}for an exact list match. Combine conditions to require all of them:metadata_filter={ "source": "slack", "review": {"status": "open"}, "tags": ["prod", "urgent"], } - include_bytes
bool– Whether image records or images attached to message records include their stored bytes. When omitted orFalse, image descriptions and metadata are returned without loading bytes. For direct image listings, set this toTrueonly with an exactrecord_idand at least one exact user, agent, or thread scope filter. This option has no effect on other record types. - record_id
str– Exact record identifier filter. When omitted, records with any identifier are returned. Scope and metadata filters remain additional constraints.
- record_type
- Returns: Records ordered from oldest to newest within the returned window.
- Return type: List[Record]
method list_relations (abstract)
List stored relations in their source-to-target orientation.
- Parameters:
- relation_type
str– Optional directed relation label to match, such as"supports"or"supersedes". Omit to include every relation type. - source_record_id
str– Optional source record identifier to match. - source_record_type
str– Optional source record type to match. - target_record_id
str– Optional target record identifier to match. - target_record_type
str– Optional target record type to match. - limit
int | None– Optional maximum number of earliest-created relations to return. When omitted, implementations may apply a safe upper bound such asMAX_LIST_LIMIT. PassNoneto return every matching stored relation. - metadata_filter
dict[str, Any] | None– Metadata filter. When omitted, no filtering is applied. When set toNone, only relations whose metadata isNoneare returned. When set to a dict, entries are combined with AND semantics. Nested dictionaries use recursive exact matching. Scalar and list values require exact equality; use{"tags": {"$array_contains": "prod"}}to match array membership,"$array_contains_any"to match any listed value, or"$not"to negate another field expression. - relation_id
str– Exact relation identifier filter. When omitted, relations with any identifier are returned. Other filters remain additional constraints.
- relation_type
- Returns: Relations ordered by creation time and identifier.
- Return type: list[RecordRelation]
Examples
store.list_relations(
source_record_id="current-memory",
relation_type="supports",
metadata_filter={"source": "manual"},
)
[RecordRelation(...)]
method list_relations_async (async)
Asynchronously list relations in source-to-target orientation.
- Parameters:
- relation_type
str– Optional directed relation label to match, such as"supports"or"supersedes". Omit to include every relation type. - source_record_id
str– Optional source record identifier to match. - source_record_type
str– Optional source record type to match. - target_record_id
str– Optional target record identifier to match. - target_record_type
str– Optional target record type to match. - limit
int | None– Optional maximum number of earliest-created relations to return. When omitted, implementations may apply a safe upper bound such asMAX_LIST_LIMIT. PassNoneto return every matching stored relation. - metadata_filter
dict[str, Any] | None– Metadata filter. When omitted, no filtering is applied. When set toNone, only relations whose metadata isNoneare returned. When set to a dict, entries are combined with AND semantics. Nested dictionaries use recursive exact matching. Scalar and list values require exact equality; use{"tags": {"$array_contains": "prod"}}to match array membership,"$array_contains_any"to match any listed value, or"$not"to negate another field expression. - relation_id
str– Optional relation identifier to match directly.
- relation_type
- Returns: Relations ordered by creation time and identifier.
- Return type: list[RecordRelation]
Examples
await store.list_relations_async(
source_record_id="current-memory", relation_type="supports"
)
[RecordRelation(...)]
method list_thread_messages (abstract)
List the message history stored for one thread.
- Parameters:
- thread_id
str– Identifier of the thread whose messages should be returned. - last_n
int | None– Optional number of most-recent messages to include. When omitted, all stored messages for the thread are returned. When combined with a sequence range, the limit applies within that range. - range_start_seq_no
int | None– Optional inclusive lower sequence boundary. Only messages whoseseq_nois at least this value are returned. - range_end_seq_no
int | None– Optional exclusive upper sequence boundary. Only messages whoseseq_nois less than this value are returned. - include_bytes
bool– Whether image parts attached to the returned messages include their stored bytes. When omitted orFalse, image descriptions and metadata are returned without loading bytes.
- thread_id
- Returns: Message records ordered from oldest to newest within the returned window.
- Return type: List[MessageRecord]
method list_thread_messages_async (async)
Asynchronously list the message history stored for one thread.
- Parameters:
- thread_id
str– Identifier of the thread whose messages should be returned. - last_n
int | None– Optional number of most-recent messages to include. When omitted, all stored messages for the thread are returned. When combined with a sequence range, the limit applies within that range. - range_start_seq_no
int | None– Optional inclusive lower sequence boundary. Only messages whoseseq_nois at least this value are returned. - range_end_seq_no
int | None– Optional exclusive upper sequence boundary. Only messages whoseseq_nois less than this value are returned. - include_bytes
bool– Whether image parts attached to the returned messages include their stored bytes. When omitted orFalse, image descriptions and metadata are returned without loading bytes.
- thread_id
- Returns: Message records ordered from oldest to newest within the returned window.
- Return type: List[MessageRecord]
method search (abstract)
Search records by similarity.
- Parameters:
- query
str | None– Natural language query. Must be provided whenquery_vectoris omitted. - query_vector
list[float] | None– Optional precomputed query embedding. Exactly one ofqueryandquery_vectormust be provided. - k
int– Maximum number of results to return. Explicit values must be at least1. This is an upper bound: the call may return fewer thankresults when filters are too restrictive, when fewer non-expired matching records exist, or because of implementation-specific search behavior. - thread_id
str | None– Optional thread scope. - user_id
str | None– Optional user and agent scope filters. - agent_id
str | None– Optional user and agent scope filters. - exact_user_match
bool– Whether each provided scope identifier must be matched exactly. - exact_agent_match
bool– Whether each provided scope identifier must be matched exactly. - exact_thread_match
bool– Whether each provided scope identifier must be matched exactly. - record_types
set[str] | None– Optional set of record types to include. - metadata_filter
dict[str, Any] | None– Optional metadata filter mapping. Entries inmetadata_filterare combined with AND semantics. Entries whose value is not a field-level operator dictionary use exact-match semantics: the requested key must exist in the stored metadata. Nested dictionaries are matched recursively. Scalar and list values are matched by exact equality; list order and length must also match. To test array membership, use a field-level operator dictionary such as{"tags": {"$array_contains": "prod"}}. A list operand for"$array_contains"means all listed values must be present;"$array_contains_any"means at least one listed value must be present. Use"$not"to negate another field-level expression at the same field, including an operator dictionary or raw exact-match value. Negated expressions match when the positive expression would fail, including missing fields; negated array membership also matches non-array fields. - include_invalid_results
bool– Whether results include memory-like records in the invalid status. Defaults toTrue. PassFalseto exclude them. - num_hops
int– Number of memory-link edges to follow from each direct memory result. Values from0through5are supported;0disables graph expansion. - max_linked_results
int– Maximum linked memories across all hops attached to each direct result.0keeps direct results without linked context. Defaults to100.
- query
- Returns:
(record, distance)pairs sorted by increasing distance. The list may contain fewer thankentries. - Return type: list[tuple[Record, float]]
- Raises:
ValueError – If
kis less than1.
Examples
store.add(
["Searchable abstract memory"],
record_type="memory",
record_ids="mem-search-abstract-docs",
)
['mem-search-abstract-docs']
store.search("Searchable", 1, record_types={"memory"})[0][0].id
'mem-search-abstract-docs'
Filter on a scalar metadata value:
store.add(
["pizza release"],
record_type="memory",
record_ids="mem-search-meta-source-docs2",
metadata={"source": "slack"},
)
['mem-search-meta-source-docs2']
any(
record.id == "mem-search-meta-source-docs2"
for record, _ in store.search(
"pizza",
k=3,
metadata_filter={"source": "slack"},
)
)
True
Filter on nested metadata:
store.add(
["pizza review"],
record_type="memory",
record_ids="mem-search-meta-review-docs2",
metadata={"review": {"status": "open"}},
)
['mem-search-meta-review-docs2']
any(
record.id == "mem-search-meta-review-docs2"
for record, _ in store.search(
"pizza",
k=3,
metadata_filter={"review": {"status": "open"}},
)
)
True
Match a list value exactly, including order:
store.add(
["pizza tags"],
record_type="memory",
record_ids="mem-search-meta-tags-docs2",
metadata={"tags": ["prod", "urgent"]},
)
['mem-search-meta-tags-docs2']
any(
record.id == "mem-search-meta-tags-docs2"
for record, _ in store.search(
"pizza",
k=5,
metadata_filter={"tags": ["prod", "urgent"]},
)
)
True
Filter when a metadata array contains a value:
any(
record.id == "mem-search-meta-tags-docs2"
for record, _ in store.search(
"pizza",
k=5,
metadata_filter={"tags": {"$array_contains": "prod"}},
)
)
True
Combine multiple metadata conditions. A record must satisfy every key:
store.add(
["pizza rollout"],
record_type="memory",
record_ids="mem-search-meta-combined-docs2",
metadata={
"source": "slack",
"review": {"status": "open"},
"tags": ["prod", "urgent"],
},
)
['mem-search-meta-combined-docs2']
any(
record.id == "mem-search-meta-combined-docs2"
for record, _ in store.search(
"pizza",
k=5,
metadata_filter={
"source": "slack",
"review": {"status": "open"},
"tags": ["prod", "urgent"],
},
)
)
True
method search_async (async)
Asynchronously search records by semantic similarity.
- Parameters:
- query
str | None– Same query text accepted bysearch. - k
int– Same maximum result count accepted bysearch. Explicit values must be at least1. - query_vector
list[float] | None– Same optional precomputed query embedding accepted bysearch. - thread_id
str | None– Same optional scope filters accepted bysearch. - user_id
str | None– Same optional scope filters accepted bysearch. - agent_id
str | None– Same optional scope filters accepted bysearch. - exact_user_match
bool– Same exact-match flags accepted bysearch. - exact_agent_match
bool– Same exact-match flags accepted bysearch. - exact_thread_match
bool– Same exact-match flags accepted bysearch. - record_types
set[str] | None– Same optional record-type filter accepted bysearch. - metadata_filter
dict[str, Any] | None– Same optional metadata filter accepted bysearch, including scalar, nested, exact-list, array-membership, and combined conditions such as{"source": "slack"},{"review": {"status": "open"}},{"tags": ["prod", "urgent"]}, and{"tags": {"$array_contains": "prod"}}. - include_invalid_results
bool– Same lifecycle-status result option accepted bysearch. - num_hops
int– Same graph-expansion depth accepted bysearch. - max_linked_results
int– Same per-direct-result linked-memory limit accepted bysearch.
- query
- Returns:
(record, distance)pairs returned by the underlyingsearchcall. - Return type: List[tuple[Record, float]]
- Raises:
ValueError – If
kis less than1.
method update (abstract)
Update stored record content, embedding data, metadata, timestamp, or expiration.
- Parameters:
- record_type
str– Logical type of the record to update. - record_id
str– Identifier of the record to update. - content
str | Mapping[str, object] | Sequence[MessageContent] | bytes | None– Canonical replacement content. Formessagerecords, pass a string or an ordered sequence of text and image content parts; use""to replace the message with empty text. For memory-like records, stores may acceptNoneto clear the stored text and associated semantic state. Omit the argument to leave content unchanged. Do not provide this together withtext. - index_text
str | list[str] | None– Optional alternative semantic payload used to recompute or replace the stored search state without changing the persisted text. A string may be chunked internally by the store. A list of non-empty strings is treated as caller-owned chunks and must not be split again. Some implementations may also persist this separately as hybrid-search text. For animagerecord, this field replaces the persisted image description. - embedding
list[float] | ndarray | list[list[float] | ndarray] | None– Optional precomputed embedding vector or list of chunk embedding vectors. When provided, this is used directly and no embedder call is made. Multiple vectors require matchingindex_textchunk lists or existing stored chunk text rows. PassNoneto explicitly clear the stored embedding when the store supports it. Stores with text-aware indexing may also allow semantic updates without an embedder or explicit embedding. - metadata
dict[str, Any] | None– Optional replacement metadata mapping. PassNoneto clear metadata when the store supports it. Replacing imagecontentrequires"image_mime_type"in this mapping. The store uses this field to save the image, but does not return it as part of the record’s metadata. - timestamp
str | None– Optional new timestamp to save with the record. It represents when the record was created. Omit this argument to leave the stored timestamp unchanged. PassNoneto clear the saved timestamp and use the time the record was added to the store when the store supports it. - ttl_days
int | None– Optional expiration refresh in days. Omit this argument together withttl_anchorto preserve the current expiration timestamp. PassNoneto clear expiration. - ttl_anchor
TimeToLiveAnchor– Optional time-to-live anchor for an expiration refresh. UseTimeToLiveAnchor.CREATED_ATfor the record creation time orTimeToLiveAnchor.TIMESTAMPfor the replacementtimestampsupplied in the same update, or the stored event timestamp whentimestampis omitted. Providingttl_anchorwithoutttl_daysuses the store or schema default time-to-live duration. Whenttl_anchoris omitted during a refresh, implementations useTimeToLiveAnchor.CREATED_AT. - status
RecordStatus– Optional replacement lifecycle status for records. -
text
str | None–Deprecated alias for
content. PassNoneto explicitly clear the stored text when the store supports it. Do not provide this together withcontent.Deprecated
Deprecated since version 26.8.0: This parameter was deprecated in 26.8.0 and will be removed in 27.1. Please use
contentinstead.
- record_type
- Returns:
Number of updated records (
0or1). A return value of0means no record was updated. - Return type: int
- Raises: ValueError – If the update payload is invalid for the store, such as omitting every optional field or providing conflicting semantic arguments.
method update_async (async)
Asynchronously update stored record content, embedding data, metadata, timestamp, or expiration.
- Parameters:
- record_type
str– Logical type of the record to update. - record_id
str– Identifier of the record to update. - content
str | Mapping[str, object] | Sequence[MessageContent] | bytes | None– Canonical replacement content. Formessagerecords, pass a string or an ordered sequence of text and image content parts; use""to replace the message with empty text. For memory-like records, stores may acceptNoneto clear the stored text and associated semantic state. Omit the argument to leave content unchanged. Do not provide this together withtext. - index_text
str | list[str] | None– Optional alternative semantic payload used to recompute or replace the stored search state without changing the persisted text. A string may be chunked internally by the store. A list of non-empty strings is treated as caller-owned chunks and must not be split again. Some implementations may also persist this separately as hybrid-search text. For animagerecord, this field replaces the persisted image description. - embedding
list[float] | ndarray | list[list[float] | ndarray] | None– Optional precomputed embedding vector or list of chunk embedding vectors. When provided, this is used directly and no embedder call is made. Multiple vectors require matchingindex_textchunk lists or existing stored chunk text rows. PassNoneto explicitly clear the stored embedding when the store supports it. Stores with text-aware indexing may also allow semantic updates without an embedder or explicit embedding. - metadata
dict[str, Any] | None– Optional replacement metadata mapping. PassNoneto clear metadata when the store supports it. Replacing imagecontentrequires"image_mime_type"in this mapping. The store uses this field to save the image, but does not return it as part of the record’s metadata. - timestamp
str | None– Optional new timestamp to save with the record. It represents when the record was created. Omit this argument to leave the stored timestamp unchanged. PassNoneto clear the saved timestamp and use the time the record was added to the store when the store supports it. - ttl_days
int | None– Optional expiration refresh in days. Omit this argument together withttl_anchorto preserve the current expiration timestamp. PassNoneto clear expiration. - ttl_anchor
TimeToLiveAnchor– Optional time-to-live anchor for an expiration refresh. UseTimeToLiveAnchor.CREATED_ATfor the record creation time orTimeToLiveAnchor.TIMESTAMPfor the replacementtimestampsupplied in the same update, or the stored event timestamp whentimestampis omitted. Providingttl_anchorwithoutttl_daysuses the store or schema default time-to-live duration. Whenttl_anchoris omitted during a refresh, implementations useTimeToLiveAnchor.CREATED_AT. - status
RecordStatus– Optional replacement lifecycle status for records. Omit it to preserve the current status. -
text
str | None–Deprecated alias for
content. PassNoneto explicitly clear the stored text when the store supports it. Do not provide this together withcontent.Deprecated
Deprecated since version 26.8.0: This parameter was deprecated in 26.8.0 and will be removed in 27.1. Please use
contentinstead.
- record_type
- Returns:
Number of updated records (
0or1). A return value of0means no record was updated. - Return type: int
- Raises: ValueError – If the update payload is invalid for the store, such as omitting every optional field or providing conflicting semantic arguments.
method update_relations (abstract)
Update mutable values on stored relations.
Omitted fields remain unchanged, except that changing to a built-in memory relation type replaces its reverse label with the fixed inverse. A DB-backed memory store also recalculates endpoint lifecycle states after a relation-type change.
- Parameters:
- relation_ids
str | list[str]– Identifier or identifiers of the relations to update. - relation_types
str | list[str]– Optional replacement directed relation label or labels. Omit this to preserve the stored labels. - opposite_relation_types
str | list[str]– Optional replacement reverse relation label or labels. Pass a label to replace it, or omit this argument to preserve it. - timestamps
str | None | list[str | None]– Optional replacement timestamp or timestamps. PassNoneto clear a stored timestamp. - metadata
dict[str, Any] | None | list[dict[str, Any] | None]– Optional replacement metadata object or objects. The supplied metadata replaces the stored object; it is not merged.
- relation_ids
- Returns: Identifiers of relations that were updated.
- Return type: list[str]
Examples
store.update_relations(
"relation-id", relation_types="supports"
)
['relation-id']
method update_relations_async (async)
Asynchronously update mutable values on stored relations.
Omitted fields remain unchanged, except that changing to a built-in memory relation type replaces its reverse label with the fixed inverse. A DB-backed memory store also recalculates endpoint lifecycle states after a relation-type change.
- Parameters:
- relation_ids
str | list[str]– Identifier or identifiers of the relations to update. - relation_types
str | list[str]– Optional replacement directed relation label or labels. Omit this to preserve the stored labels. - opposite_relation_types
str | list[str]– Optional replacement reverse relation label or labels. Pass a label to replace it, or omit this argument to preserve it. - timestamps
str | None | list[str | None]– Optional replacement timestamp or timestamps. PassNoneto clear a stored timestamp. - metadata
dict[str, Any] | None | list[dict[str, Any] | None]– Optional replacement metadata object or objects. The supplied metadata replaces the stored object; it is not merged.
- relation_ids
- Returns: Identifiers of relations that were updated.
- Return type: list[str]
Examples
await store.update_relations_async(
"relation-id", relation_types="supports"
)
['relation-id']
Oracle DB Store
class oracleagentmemory.core.OracleDBMemoryStore
Bases: OracleMemoryStore
Database-backed persistence for messages, documents, memories, and actor profiles.
Create an Oracle DB store.
- Parameters:
- embedder
IEmbedder | None– Embedder used when the store needs local vector embeddings. May beNonewhen callers always provide precomputed vectors, or when keyword search is used with text-only writes and text queries.SearchStrategy.HYBRIDrequires anOracleDBEmbedderhere so the managed hybrid index can use this embedder’s in-database model. - pool
Any– Oracle DB connection or pool. Passing a raw connection enables single-session mode for this store instance: concurrent store calls are serialized locally to preserve the row-lock and transaction assumptions used by write operations. Use a connection pool for concurrent requests. - schema_policy
SchemaPolicy | str– Controls how the managed schema is opened or prepared. Defaults to requiring an existing, up-to-date schema and makes no DDL changes. For a store identified bymemory_store_id,SchemaPolicy.CREATE_IF_NECESSARYcreates or repairs the schema when needed;SchemaPolicy.RECREATEdrops and rebuilds it. Older schema versions require a package schema upgrade before they can be repaired. Whenschema_owneris set, useSchemaPolicy.REQUIRE_EXISTINGfor ordinary cross-schema access orSchemaPolicy.NO_CHECKfor Deep Data Security runtime access. Both prevent managed schema DDL, including schema creation, repair, recreation, and first hybrid-index creation; perform those actions while connected as the owning database user withoutschema_owner. Neither mode makes the store read-only: normal memory reads and writes use the connection user’s effective database authorization. For Deep Data Security runtime access, useSchemaPolicy.NO_CHECKand create the store while anOracleMemoryEndUserSecurityContextis active. The resulting store requires an active end-user context for every later database operation. Schema policies other thanNO_CHECKreject active end-user contexts so schema lifecycle work cannot accidentally run as an end user. - vector_dim
int | None– Optional embedding dimension for local vector storage. Pass a positive integer to create the managed embedding column and vector index, and to validate existing schema metadata against that dimension. PassNoneor omit the argument when this store does not need local vector storage. Keyword and hybrid search can operate from stored search text without the local embedding column. Vector search requires local vector storage. When this argument is omitted and the effective search backend is vector search, the store usesembedder.embedding_dimensionwhen an embedder is available. -
table_name_prefix
str–Optional prefix added to managed table/index names. Pass either this or
memory_store_id, not both.Deprecated
Deprecated since version 26.6.0: This parameter was deprecated in 26.6.0 and will be removed in 27.1. Please use
memory_store_idinstead. - memory_store_id
str– Stable ID for the managed DB memory store. Reuse the same ID to reopen the same managed store. The ID is joined to managed DB object names with an underscore, so it must start with a letter, contain only letters, numbers, and underscores, and be at most 16 characters. Pass either this ortable_name_prefix, not both. If omitted, the store usestable_name_prefixor the unprefixed default whentable_name_prefixis also omitted. Creating, repairing, or recreating a store in the connection user’s schema requires a compatible DBMS_AGENT_MEMORY_STORE package in that schema. - schema_owner
str– Optional schema owner for an existing managed memory store. Omit this option to use the connection user’s schema. Thepoolargument may be a raw database connection or a connection pool; use this option when it belongs to an application DB user that has grants on tables owned by another user. This option is only for runtime access to an already-created managed memory store. UseSchemaPolicy.REQUIRE_EXISTINGfor ordinary cross-schema access orSchemaPolicy.NO_CHECKwith an active end-user security context for a Deep Data Security-protected store. Create, upgrade, or recreate the managed memory store while connected as the schema owner and omit this option. Pass an unquoted identifier; lowercase input is normalized to uppercase, and quoted, case-sensitive schema owners are not supported. GrantCREATE SESSIONand the required object privileges to the application DB user; see theDatabase Users and Privilegessection of the troubleshooting guide for the exact grants. As an alternative, expose same-named managed-object views in the runtime schema and omitschema_owner; this is supported only forSchemaPolicy.REQUIRE_EXISTING. - search_strategy
SearchStrategy–SearchStrategyvalue that selects the backend forsearch(). UseSearchStrategy.VECTOR(default) for vector-only retrieval,SearchStrategy.HYBRIDto query a managed Oracle hybrid vector index over the stored search text, orSearchStrategy.KEYWORDto rank by keyword/text matching over the stored search text without vector fusion.KEYWORDdoes not require an embedder.HYBRIDrequiresembedderto be anOracleDBEmbedderso the managed hybrid index uses the same in-database model as the main store embedder. If a keyword client opens an existing hybrid schema, the store can use the text branch of that hybrid index. Startup fails when an incompatible strategy is used with an existing schema because that schema may not contain the stored search state the strategy needs. Whenschema_policy=SchemaPolicy.REQUIRE_EXISTINGand this argument is omitted, the store best-effort detects the schema’s stored search mode from managed metadata and uses that mode when available. - search_index_sync
SearchIndexSyncMode–SearchIndexSyncModevalue that selects the managed search-index refresh behavior forSearchStrategy.HYBRIDandSearchStrategy.KEYWORD.SearchIndexSyncMode.ON_COMMITis the default and makes records searchable as soon as the write transaction commits.SearchIndexSyncMode.MANUALleaves refresh to an explicit database-side sync operation.SearchIndexSyncMode.AUTOlets Oracle refresh the managed hybrid index asynchronously and is supported only withSearchStrategy.HYBRID; keyword search rejectsAUTO. - memory_retention_config
MemoryRetentionConfig– Optional memory retention configuration for DB-backed messages and memories.MemoryRetentionConfig.default_ttl_daysis used when a new write omitsttl_days.MemoryRetentionConfig.max_ttl_daysclamps explicit per-record durations above the configured maximum with a warning and, when set, makesttl_days=Noneuse that maximum instead of creating non-expiring rows. WithSchemaPolicy.CREATE_IF_NECESSARY, an explicit configuration refreshes the stored metadata on an existing up-to-date managed schema, but it does not update the existing expiration dates; omitting it keeps the existing setting. If an explicit configuration leavesdefault_ttl_daysormax_ttl_daysatNOT_SET_MARKER, the SDK resolves that attribute to its default value (None) before comparing or storing schema metadata. Choose this configuration based on the expected information stored in records, why the application retains it, and any application or regulatory retention commitments.
- embedder
- Raises:
RuntimeError – If an end-user security context is active with a schema policy
other than
SchemaPolicy.NO_CHECK, or if aNO_CHECKruntime store is opened or used without an active end-user security context.
Warning: SchemaPolicy.CREATE_IF_NECESSARY can be more expensive than normal
store startup because it may repair managed schema objects before
initialization succeeds. Plan repair work as a maintenance operation
when a schema may contain many rows. A store on an older schema version
requires a package schema upgrade before initialization.
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. Store initialization 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.
Creating that managed hybrid index also creates a
DBMS_VECTOR_CHAIN vectorizer preference named by the managed
schema. The preference stores lightweight vectorizer configuration
metadata from the configured OracleDBEmbedder model. It can be
inspected with Oracle Text preference views such as
CTX_USER_PREFERENCES and CTX_USER_PREFERENCE_VALUES.
method add
Add records to the Oracle DB store.
- Parameters:
- contents
Sequence[str | Mapping[str, object] | Sequence[MessageContent] | bytes | None]– Read-only sequence of record payloads. Message entries may contain orderedMessageContentparts. Thread-summary entries may be mappings, strings that become{"text": value}objects, orNonestored as JSONnull. Text values are also used for search unlessindex_textsare provided. For other record types,Nonemay fall back tometadata["content"]. Explicit empty strings are preserved. - record_type
str– Logical record type to create, such as"message","memory","guideline","fact","preference","user_profile","agent_profile", or"thread_summary". - index_texts
list[str | list[str] | None]– Optional alternative payloads used as search text. Use this to control what DB-backed keyword or hybrid search indexes. Each outer list entry aligns with one record. A string entry may be chunked by the store. A list entry is treated as caller-owned chunks and written as-is toRECORD_CHUNKS.chunk_text. Whenembeddingsare also provided, list entries require exactly one vector per chunk; string entries accept only a single vector for that record. -
embeddings
list[list[float] | ndarray | list[list[float] | ndarray]]–Optional precomputed embedding vectors aligned with
contents. Each record entry may be either one vector or a list of chunk vectors. When local vector storage is configured, these vectors are stored directly as the record’s vector representation instead of calling the store’s embedder to create local vectors for the write. A single vector represents the whole semantic text, even when the configured chunker would otherwise split it. Multiple chunk vectors require matchingindex_textschunk lists.In
SearchStrategy.VECTOR, vector search ranks against those stored vectors. InSearchStrategy.HYBRIDorSearchStrategy.KEYWORD, DB-backed search ranks through the stored search text and Oracle-managed text or hybrid index state, so add-time embeddings affect only any configured local vector storage, not that active search strategy. If this store was configured without local vector storage, provideindex_textsinstead ofembeddingsto override the text visible to those text-aware indexes. - record_ids
str | None | list[str | None]– Optional caller-visible identifiers. A single string may be used for one-record inserts, while lists must align withcontents. Generated identifiers are returned when this field is omitted. - thread_ids
str | None | list[str | None]– Optional thread identifiers associated with the inserted records. Scalar values may be broadcast across aligned inputs. - user_ids
str | None | list[str | None]– Optional user identifiers associated with the inserted records. Scalar values may be broadcast across aligned inputs. When omitted on aSchemaPolicy.NO_CHECKruntime store, the store uses the active end-user security context’s username. PassNoneexplicitly to preserve an unscoped user ID. - agent_ids
str | None | list[str | None]– Optional agent identifiers associated with the inserted records. Scalar values may be broadcast across aligned inputs. - roles
str | None | list[str | None]– Optional message roles such as"user"or"assistant". Used only whenrecord_typeis"message". - timestamps
str | None | list[str | None]– Optional timestamps to save with the records. Each timestamp represents when the record was created. Scalar values may be broadcast across aligned inputs. Omitted orNoneentries leave the event timestamp unset. Whenttl_anchorisTimeToLiveAnchor.TIMESTAMP, every affected record must have a concrete ISO-8601 timestamp value. ISO-8601 timestamps without a timezone are treated as UTC. - metadata
dict[str, Any] | None | list[dict[str, Any] | None]– Optional metadata dictionaries. Metadata may include"content"as a fallback source when a text value is omitted rather than set to"". Image writes require"image_mime_type"with"image/png","image/jpeg", or"image/webp". The store uses this field to save the image, but does not return it as part of the record’s metadata. - ttl_days
int | None | list[int | None]– Optional time-to-live duration in days for message and memory-like records. Omit this argument to useMemoryRetentionConfig.default_ttl_daysfrom the managed schema. PassNoneto useMemoryRetentionConfig.max_ttl_dayswhen the retention configuration sets one, or to create a non-expiring record when it does not. Values aboveMemoryRetentionConfig.max_ttl_daysare clamped to that maximum with a warning. Scalar values may be broadcast across aligned inputs. - ttl_anchor
TimeToLiveAnchor | list[TimeToLiveAnchor]– Optional time-to-live anchor. UseTimeToLiveAnchor.CREATED_ATto expire relative to the database creation time, orTimeToLiveAnchor.TIMESTAMPto expire relative to the provided event timestamp. When omitted, expiration usesTimeToLiveAnchor.CREATED_AT. Timestamp-anchored expiration requires a concrete ISO-8601 timestamp for each inserted record. ISO-8601 timestamps without a timezone are treated as UTC. - statuses
RecordStatus | list[RecordStatus]– Optional lifecycle status for records that support it. Provide oneRecordStatusvalue to apply it to every input record, or a list of statuses aligned withcontents. Omit this argument to useRecordStatus.VALID. - **store_kwargs (Any) – DB write options.
batch_sizecontrols the executemany batch size and defaults to256.
- contents
- Returns: Identifiers for inserted records, in the same logical order as the input.
- Return type: list[str]
Examples
store.add(
["Index this stored text"],
record_type="memory",
record_ids="mem-db-add-docs",
)
['mem-db-add-docs']
store.add(
["Stored text"],
record_type="memory",
index_texts=["Search this text"],
record_ids="mem-db-index-text-docs",
)
['mem-db-index-text-docs']
store.add(
["Short-lived event"],
record_type="memory",
record_ids="mem-db-ttl-docs",
timestamps="2026-01-01T12:00:00+00:00",
ttl_days=7,
ttl_anchor=TimeToLiveAnchor.TIMESTAMP,
)
['mem-db-ttl-docs']
method add_agent
Add an agent profile record.
- Parameters:
- agent_id
str– Agent identifier. - information
str– Free-form information about the agent. This text is stored as the profile content and used to build the profile’s searchable representation. - metadata
dict[str, Any] | None– Optional metadata mapping stored on the agent profile row.
- agent_id
- Returns: Identifier of the inserted agent profile record.
- Return type: str
Notes
Agent profile records are unscoped. The inserted public record
identifier is the same value passed as agent_id.
Examples
store.add_agent("a-docs-agent", "Support assistant")
'a-docs-agent'
method add_agent_async (async)
Asynchronously add an agent profile record.
- Parameters:
- agent_id
str– Stable identifier for the agent profile. - information
str– Free-form text describing the agent. - metadata
dict[str, Any] | None– Optional metadata mapping stored on the agent profile row.
- agent_id
- Returns: Identifier of the created agent profile record.
- Return type: str
method add_async (async)
Asynchronously add row-oriented records to the store.
Accepts the same arguments and returns the same identifiers as add().
- Parameters:
- contents
Sequence[str | Mapping[str, object] | Sequence[MessageContent] | bytes | None] - record_type
str - index_texts
list[str | list[str] | None] - embeddings
list[list[float] | ndarray | list[list[float] | ndarray]] - record_ids
str | None | list[str | None] - thread_ids
str | None | list[str | None] - user_ids
str | None | list[str | None] - agent_ids
str | None | list[str | None] - roles
str | None | list[str | None] - timestamps
str | None | list[str | None] - metadata
dict[str, Any] | None | list[dict[str, Any] | None] - ttl_days
int | None | list[int | None] - ttl_anchor
TimeToLiveAnchor | list[TimeToLiveAnchor] - statuses
RecordStatus | list[RecordStatus] - store_kwargs
Any
- contents
- Return type: list[str]
method add_batches
Add caller-prepared logical batches to the store.
- Parameters:
- batches
list[PendingRecordBatch]– Fully prepared logical batches to persist. Each batch should carry its own per-record fields such asrecord_type, scope values, roles, timestamps, and metadata. - **store_kwargs (Any) – Implementation-specific write options forwarded to the concrete store.
- batches
- Returns: Identifiers for the inserted records, in the same logical order as the input batches and rows.
- Return type: List[str]
Examples
store.add_batches(
[
PendingRecordBatch(
contents=["pizza batch"],
record_type="memory",
record_ids="mem-batch-docs",
)
]
)
['mem-batch-docs']
method add_batches_async (async)
Asynchronously add caller-prepared logical batches to the store.
Accepts the same arguments and returns the same identifiers as
add_batches().
- Parameters:
- batches
list[PendingRecordBatch] - store_kwargs
Any
- batches
- Return type: list[str]
method add_relations
Store one or more memory-to-memory relations atomically.
Scalar values are broadcast across the source-ID batch; lists must be aligned. Only one relation orientation may be stored for an endpoint pair. Built-in memory link labels receive their fixed reverse label, and lifecycle labels update endpoint state in the same transaction.
- Parameters:
- source_record_ids
str | list[str]– Source memory identifiers, as a scalar or an aligned list. - source_record_types
str | list[str]– Memory-like types for the source records. - target_record_ids
str | list[str]– Target memory identifiers, as a scalar or an aligned list. - target_record_types
str | list[str]– Memory-like types for the target records. - relation_types
str | list[str]– Directed relation labels. - opposite_relation_types
str | list[str]– Optional reverse labels for custom relation types. This describes the reverse view of the stored relation; it does not create a second relation in the reverse direction. - relation_ids
str | None | list[str | None]– Optional stable relation identifiers. Omit to generate identifiers. - timestamps
str | None | list[str | None]– Optional timestamps stored with the relations. - metadata
dict[str, Any] | None | list[dict[str, Any] | None]– Optional metadata stored with the relations.
- source_record_ids
- Returns: Created relation identifiers in input order.
- Return type: list[str]
Examples
store.add_relations(
"new-memory", "memory", "old-memory", "memory", "supersedes"
)
['relation-id']
method add_relations_async (async)
Asynchronously store one or more directed relations.
Scalar values are broadcast across the source-record batch. List
values must have the same length. Only one orientation can be stored
for an endpoint pair. Use opposite_relation_types to describe the
reverse view rather than adding a second reverse relation.
- Parameters:
- source_record_ids
str | list[str]– Identifier or identifiers of records at the source end of each directed relation. - source_record_types
str | list[str]– Record type or types forsource_record_ids. Supply one value for all sources or one value for each relation. - target_record_ids
str | list[str]– Identifier or identifiers of records at the target end of each directed relation. - target_record_types
str | list[str]– Record type or types fortarget_record_ids. Supply one value for all targets or one value for each relation. - relation_types
str | list[str]– Directed relation label or labels. Supply one value for all relations or one value for each relation. - opposite_relation_types
str | list[str]– Optional label or labels for the reverse view of each relation. For built-in memory relation types, omission uses the predefined reverse label. For custom relation types, omission uses the same label in both directions. - relation_ids
str | None | list[str | None]– Optional stable identifier or identifiers. Omit this to let the store generate identifiers. - timestamps
str | None | list[str | None]– Optional timestamp or timestamps to store on the relations. - metadata
dict[str, Any] | None | list[dict[str, Any] | None]– Optional metadata object or objects to store on the relations.
- source_record_ids
- Returns: Relation identifiers in input order.
- Return type: list[str]
Examples
await store.add_relations_async(
"new", "memory", "old", "memory", "supersedes"
)
['relation-id']
method add_user
Add a user profile record.
- Parameters:
- user_id
str– User identifier. When omitted on aSchemaPolicy.NO_CHECKruntime store, the store uses the active end-user security context’s username. Otherwise, provide this argument explicitly. - information
str– Required free-form information about the user. This text is stored as the profile content and used to build the profile’s searchable representation. - metadata
dict[str, Any] | None– Optional metadata mapping stored on the user profile row.
- user_id
- Returns: Identifier of the inserted user profile record.
- Return type: str
Notes
User profile records are unscoped. The inserted public record
identifier is the explicit or inferred user_id.
Examples
store.add_user("u-docs-profile", "Prefers concise answers.")
'u-docs-profile'
method add_user_async (async)
Asynchronously add a user profile record.
- Parameters:
- user_id
str– Stable identifier for the user profile. - information
str– Free-form text describing the user. - metadata
dict[str, Any] | None– Optional metadata mapping stored on the user profile row.
- user_id
- Returns: Identifier of the created user profile record.
- Return type: str
method delete
Delete one managed row and its chunk rows by identifier.
- Parameters:
- record_type
str– Record type label to delete. Supported types include"thread","message","memory","guideline","fact","preference","user_profile", and"agent_profile", and"thread_summary". - record_id
str– Identifier to delete. - cascade
bool– WhenTrue, expand supported top-level targets such as actor profiles to their scoped child rows inside the same transaction. For a user-profile or agent-profile target, this deletes the owned thread rows first, which removes their thread-scoped message and memory-table rows, then deletes any remaining directly actor-scoped messages and memory-like rows (memory,guideline,fact,preference). This scoped cleanup still runs when the matching profile row is already absent.
- record_type
- Returns:
Number of requested top-level targets removed, typically
0or1. Cascaded child rows are not counted separately, so this may still be0when a missing actor profile triggers scoped cleanup. - Return type: int
Notes
The operation runs inside one transaction. When cascade is enabled
for a supported top-level target, the profile delete and all scoped
child deletes are committed or rolled back together.
Examples
store.add(["Delete me"], record_type="memory", record_ids="mem-delete-docs")
['mem-delete-docs']
store.delete("memory", "mem-delete-docs")
1
method delete_async (async)
Asynchronously delete one stored record by identifier.
- Parameters:
- record_type
str– Logical type of the record to remove. - record_id
str– Identifier of the record to remove. - cascade
bool– WhenTrue, apply any store-supported cascading delete behavior for the requested top-level targets inside the same delete operation. This is primarily used for targets such as actor profiles that own additional scoped records. For example, a user-profile or agent-profile cascade may delete owned threads themselves, the thread-scoped messages and memory-like records removed with those threads, and any remaining directly actor-scoped records such as messages, memories, guidelines, facts, or preferences. For actor-profile deletes, this scoped cleanup may still run when the matching profile row is already absent.
- record_type
- Returns:
Number of requested top-level records deleted, typically
0or1. Cascaded child rows are not counted separately, so this may still be0when a missing actor profile triggers scoped cleanup. - Return type: int
method delete_relations
Delete relations by identifier and recalculate lifecycle state.
- Parameters:
relation_ids
str | list[str]– Identifier or identifiers of the relations to delete. - Returns: Number of relations deleted.
- Return type: int
Examples
store.delete_relations("relation-id")
1
method delete_relations_async (async)
Asynchronously delete relations by identifier.
Lifecycle state is recalculated from the relations that remain.
- Parameters:
relation_ids
str | list[str]– Identifier or identifiers of the relations to delete. - Returns: Number of deleted relations.
- Return type: int
Examples
await store.delete_relations_async("relation-id")
1
method delete_thread
Delete a thread and its associated stored rows.
- Parameters:
thread_id
str– Thread identifier whose rows should be removed, including the thread row, dependent child rows, and explicit chunk-row cleanup. - Returns:
Number of deleted thread rows (
0or1). - Return type: int
Notes
Use this operation when you need thread-scoped cascading cleanup. In the DB-backed store, deleting the thread removes the managed thread row together with associated message and memory rows, plus the search data maintained for retrieval. This is broader than a message-level delete, which removes only the raw message row. Thread deletion removes dependent message and memory rows together with their associated retrieval data in the same transaction.
Examples
store.delete_thread("c1")
0
method delete_thread_async (async)
Asynchronously delete a thread and its associated stored data.
- Parameters:
thread_id
str– Identifier of the thread to remove. - Returns:
Number of deleted thread records, typically
0or1. - Return type: int
Notes
This is the store-level operation for removing a thread and the thread-scoped records managed by the store. Prefer thread deletion when retention requirements call for deleting both source messages and derived thread-scoped memory data, because message-level deletes do not imply that separately persisted derived records are removed.
method get
Retrieve a stored record by identifier.
- Parameters:
- record_type
str– Record type label resolving to a managed row, such as"message","memory","guideline","fact","preference","thread","user_profile", or"agent_profile", or"thread_summary". - record_id
str– Identifier to look up. - include_bytes
bool– Whether to load image bytes for image records or attached images for message records. Defaults toFalse.
- record_type
- Returns:
Populated record with decoded metadata when found, otherwise
None. - Return type: Record | None
Examples
store.add(["Remember this"], record_type="memory", record_ids="mem-get-docs")
['mem-get-docs']
store.get("memory", "mem-get-docs").id
'mem-get-docs'
method get_async (async)
Asynchronously retrieve one stored record by type and identifier.
- Parameters:
- record_type
str– Logical type of the record to retrieve, such as"thread","message","memory","guideline","fact","preference","user_profile","agent_profile", or"image". - record_id
str– Identifier of the record to retrieve. - include_bytes
bool– Whether to load stored image bytes. For a message record, this controls whether attached images include their bytes. For an image record, it controls whether the standalone image bytes are loaded. This option has no effect on other record types.
- record_type
- Returns:
The stored record when found, otherwise
None. A"thread"lookup returns aThreadRecordwith thread metadata, runtime configuration, runtime state, and the creation timestamp populated when the store supports persisted threads. - Return type: Record | None
method get_relation
Return one relation identified by ID or complete endpoint tuple.
Provide relation_id alone, or provide one complete source-to-target
endpoint tuple.
- Parameters:
- source_record_id
str– Source record identifier. Required with the other endpoint-tuple fields whenrelation_idis omitted. - source_record_type
str– Source record type. Required with the other endpoint-tuple fields whenrelation_idis omitted. - target_record_id
str– Target record identifier. Required with the other endpoint-tuple fields whenrelation_idis omitted. - target_record_type
str– Target record type. Required with the other endpoint-tuple fields whenrelation_idis omitted. - relation_type
str– Directed relation label. Required with the other endpoint-tuple fields whenrelation_idis omitted. - relation_id
str– Relation identifier to match directly. Provide this argument alone rather than combining it with endpoint-tuple fields.
- source_record_id
- Returns:
The matching stored relation, or
Nonewhen it does not exist. - Return type: RecordRelation | None
Examples
store.get_relation(relation_id="relation-id")
RecordRelation(...)
store.get_relation(
"source-id", "memory", "target-id", "fact", "supports"
)
RecordRelation(...)
method get_relation_async (async)
Asynchronously retrieve one relation by ID or endpoint tuple.
Provide relation_id alone, or provide one complete source-to-target
endpoint tuple.
- Parameters:
- source_record_id
str– Source record identifier. Required with the other endpoint-tuple fields whenrelation_idis omitted. - source_record_type
str– Source record type. Required with the other endpoint-tuple fields whenrelation_idis omitted. - target_record_id
str– Target record identifier. Required with the other endpoint-tuple fields whenrelation_idis omitted. - target_record_type
str– Target record type. Required with the other endpoint-tuple fields whenrelation_idis omitted. - relation_type
str– Directed relation label. Required with the other endpoint-tuple fields whenrelation_idis omitted. - relation_id
str– Relation identifier to match directly. Provide this argument alone rather than combining it with endpoint-tuple fields.
- source_record_id
- Returns:
The matching relation, or
Nonewhen it does not exist. - Return type: RecordRelation | None
Examples
await store.get_relation_async(relation_id="relation-id")
RecordRelation(...)
method list
Enumerate persisted records for a record type.
- Parameters:
- record_type
str– Record type label (e.g."thread","message","memory","guideline","fact","preference","thread","user_profile", or"agent_profile"). - limit
int | None– Optional maximum number of records to return. When omitted, the store uses its default listing cap. PassNoneto disable that cap and return every matching record. - thread_id
str | None– Exact thread-scope filter. When omitted, no filtering is applied. When set toNone, only rows whosethread_idis SQLNULLare returned. Unscoped record types ignore this filter. Whenrecord_typeis"thread",thread_idshould not be set; userecord_idto select a specific thread. - user_id
str | None– Exact user-scope filter. When omitted, no filtering is applied. When set toNone, only rows whoseuser_idis SQLNULLare returned. Unscoped record types ignore this filter. - agent_id
str | None– Exact agent-scope filter. When omitted, no filtering is applied. When set toNone, only rows whoseagent_idis SQLNULLare returned. Unscoped record types ignore this filter. -
metadata_filter
dict[str, Any] | None–Metadata filter. When omitted, no filtering is applied. When set to
None, only records with no stored metadata are returned. When set to a dict, entries inmetadata_filterare combined with AND semantics. Entries whose value is not a field-level operator dictionary use exact-match semantics: the requested key must exist in the stored metadata. Nested dictionaries are matched recursively. Scalar and list values are matched by exact equality; list order and length must also match. To test array membership, use a field-level operator dictionary such as{"tags": {"$array_contains": "prod"}}. A list operand for"$array_contains"means all listed values must be present;"$array_contains_any"means at least one listed value must be present. Use"$not"to negate another field-level expression at the same field, including an operator dictionary or raw exact-match value. Negated expressions match when the positive expression would fail, including missing fields; negated array membership also matches non-array fields. Examples includemetadata_filter={"source": "slack"}for a scalar field,metadata_filter={"review": {"status": "open"}}for a nested field, andmetadata_filter={"tags": ["prod", "urgent"]}for an exact list match. Combine conditions to require all of them:metadata_filter={ "source": "slack", "review": {"status": "open"}, "tags": ["prod", "urgent"], } - include_bytes
bool– Whether image records or images attached to message records include their stored bytes. Defaults toFalse. Direct image listings require arecord_idand at least one exact user, agent, or thread scope filter when this isTrue. - record_id
str– Exact record identifier filter. When omitted, records with any identifier are returned. Scope and metadata filters remain additional constraints.
- record_type
- Returns: Records ordered by insertion order.
- Return type: list[Record]
Notes
"user_profile" and "agent_profile" are unscoped record types.
For those record types, thread_id, user_id, and agent_id
are ignored and actor identity remains in record.id.
"thread" records expose the thread identifier as both
record.id and record.thread_id.
Examples
store.add(
["First listed", "Second listed"],
record_type="memory",
record_ids=["mem-list-docs-1", "mem-list-docs-2"],
)
['mem-list-docs-1', 'mem-list-docs-2']
[record.id for record in store.list("memory", limit=2)]
['mem-list-docs-1', 'mem-list-docs-2']
store.add_user("u-list-docs", "Prefers concise answers.")
'u-list-docs'
any(
record.id == "u-list-docs"
for record in store.list("user_profile", user_id=None, limit=10)
)
True
method list_async (async)
Asynchronously list stored records for one record type.
- Parameters:
- record_type
str– Logical record type to enumerate, such as"thread","message","memory","guideline","fact","preference","user_profile","agent_profile", or"image". - limit
int | None– Optional maximum number of most-recent records to return. When omitted, implementations may apply a safe upper bound such asMAX_LIST_LIMIT. PassNoneto disable that cap and return every matching record. - thread_id
str | None– Exact thread-scope filter. When omitted, no filtering is applied. When set toNone, only records whosethread_idisNoneare returned. Unscoped record types ignore this filter. Whenrecord_typeis"thread",thread_idshould not be set; userecord_idto select a specific thread. - user_id
str | None– Exact user-scope filter. When omitted, no filtering is applied. When set toNone, only records whoseuser_idisNoneare returned. Unscoped record types ignore this filter. - agent_id
str | None– Exact agent-scope filter. When omitted, no filtering is applied. When set toNone, only records whoseagent_idisNoneare returned. Unscoped record types ignore this filter. -
metadata_filter
dict[str, Any] | None–Metadata filter. When omitted, no filtering is applied. When set to
None, only records whose metadata isNoneare returned. When set to a dict, entries inmetadata_filterare combined with AND semantics. Entries whose value is not a field-level operator dictionary use exact-match semantics: the requested key must exist in the stored metadata. Nested dictionaries are matched recursively. Scalar and list values are matched by exact equality; list order and length must also match. To test array membership, use a field-level operator dictionary such as{"tags": {"$array_contains": "prod"}}. A list operand for"$array_contains"means all listed values must be present;"$array_contains_any"means at least one listed value must be present. Use"$not"to negate another field-level expression at the same field, including an operator dictionary or raw exact-match value. Negated expressions match when the positive expression would fail, including missing fields; negated array membership also matches non-array fields. Examples includemetadata_filter={"source": "slack"}for a scalar field,metadata_filter={"review": {"status": "open"}}for a nested field, andmetadata_filter={"tags": ["prod", "urgent"]}for an exact list match. Combine conditions to require all of them:metadata_filter={ "source": "slack", "review": {"status": "open"}, "tags": ["prod", "urgent"], } - include_bytes
bool– Whether image records or images attached to message records include their stored bytes. When omitted orFalse, image descriptions and metadata are returned without loading bytes. For direct image listings, set this toTrueonly with an exactrecord_idand at least one exact user, agent, or thread scope filter. This option has no effect on other record types. - record_id
str– Exact record identifier filter. When omitted, records with any identifier are returned. Scope and metadata filters remain additional constraints.
- record_type
- Returns: Records ordered from oldest to newest within the returned window.
- Return type: List[Record]
method list_relations
List relations in their source-to-target orientation.
- Parameters:
- relation_type
str– Optional directed relation label to match, such as"supports"or"supersedes". Omit to include every relation type. - source_record_id
str– Optional source record identifier to match. - source_record_type
str– Optional source record type to match. - target_record_id
str– Optional target record identifier to match. - target_record_type
str– Optional target record type to match. - limit
int | None– Optional maximum number of earliest-created relations to return. When omitted, the store usesMAX_LIST_LIMIT. PassNoneto return every matching stored relation. - metadata_filter
dict[str, Any] | None– Metadata filter. When omitted, no filtering is applied. When set toNone, only relations whose metadata isNoneare returned. When set to a dict, entries are combined with AND semantics. Nested dictionaries use recursive exact matching. Scalar and list values require exact equality; use{"tags": {"$array_contains": "prod"}}to match array membership,"$array_contains_any"to match any listed value, or"$not"to negate another field expression. - relation_id
str– Exact relation identifier filter. When omitted, relations with any identifier are returned. Other filters remain additional constraints.
- relation_type
- Returns: Relations ordered by creation time and identifier.
- Return type: list[RecordRelation]
Examples
store.list_relations(
source_record_id="current-memory",
relation_type="supports",
metadata_filter={"source": "manual"},
)
[RecordRelation(...)]
method list_relations_async (async)
Asynchronously list relations in source-to-target orientation.
- Parameters:
- relation_type
str– Optional directed relation label to match, such as"supports"or"supersedes". Omit to include every relation type. - source_record_id
str– Optional source record identifier to match. - source_record_type
str– Optional source record type to match. - target_record_id
str– Optional target record identifier to match. - target_record_type
str– Optional target record type to match. - limit
int | None– Optional maximum number of earliest-created relations to return. When omitted, implementations may apply a safe upper bound such asMAX_LIST_LIMIT. PassNoneto return every matching stored relation. - metadata_filter
dict[str, Any] | None– Metadata filter. When omitted, no filtering is applied. When set toNone, only relations whose metadata isNoneare returned. When set to a dict, entries are combined with AND semantics. Nested dictionaries use recursive exact matching. Scalar and list values require exact equality; use{"tags": {"$array_contains": "prod"}}to match array membership,"$array_contains_any"to match any listed value, or"$not"to negate another field expression. - relation_id
str– Optional relation identifier to match directly.
- relation_type
- Returns: Relations ordered by creation time and identifier.
- Return type: list[RecordRelation]
Examples
await store.list_relations_async(
source_record_id="current-memory", relation_type="supports"
)
[RecordRelation(...)]
method list_thread_messages
Return persisted messages for a thread.
- Parameters:
- thread_id
str– Thread identifier whose messages should be returned. - last_n
int | None– Optional number of most-recent messages to return. - range_start_seq_no
int | None– Optional inclusive lower sequence boundary. - range_end_seq_no
int | None– Optional exclusive upper sequence boundary. - include_bytes
bool– Whether image parts attached to the returned messages include their stored bytes. Defaults toFalse.
- thread_id
- Returns: Message records ordered by insertion order.
- Return type: list[MessageRecord]
Examples
store.list_thread_messages("c1")
[]
method list_thread_messages_async (async)
Asynchronously list the message history stored for one thread.
- Parameters:
- thread_id
str– Identifier of the thread whose messages should be returned. - last_n
int | None– Optional number of most-recent messages to include. When omitted, all stored messages for the thread are returned. When combined with a sequence range, the limit applies within that range. - range_start_seq_no
int | None– Optional inclusive lower sequence boundary. Only messages whoseseq_nois at least this value are returned. - range_end_seq_no
int | None– Optional exclusive upper sequence boundary. Only messages whoseseq_nois less than this value are returned. - include_bytes
bool– Whether image parts attached to the returned messages include their stored bytes. When omitted orFalse, image descriptions and metadata are returned without loading bytes.
- thread_id
- Returns: Message records ordered from oldest to newest within the returned window.
- Return type: List[MessageRecord]
method search
Search records by similarity.
The active search backend depends on the store’s configured
SearchStrategy. SearchStrategy.VECTOR ranks the query vector
against stored record vectors. SearchStrategy.HYBRID queries
Oracle’s managed hybrid index over the stored search text and its
managed index state. SearchStrategy.KEYWORD ranks only by text
matching over the stored search text.
- Parameters:
- query
str | None– Optional natural-language text used to find matching or similar records. Provide at least one non-whitespace character whenquery_vectoris omitted. Vector search embeds this text; keyword search matches it against stored search text; hybrid search uses it for both text and vector retrieval. When the text exceeds the configured chunk size, the store searches each query chunk separately and merges the ranked results with reciprocal rank fusion. - query_vector
list[float] | None– Optional precomputed query embedding. Exactly one ofqueryandquery_vectormust be provided. In vector search, this is compared with stored record vectors. In hybrid search, it is sent to Oracle’s managed hybrid index as the query-side vector input and does not cause the DB store to compare against add-time or update-time stored vectors directly. Keyword search does not acceptquery_vector. The vector must be non-empty, one- dimensional, and contain only finite numeric values. In hybrid search, its dimension must match the configuredOracleDBEmbeddermodel. - k
int– Maximum number of results to return. Explicit values must be at least1. This is an upper bound: the call may return fewer thankresults when filters are too restrictive, when fewer non-expired matching records exist, or because of implementation-specific search behavior. - thread_id
str | None– Optional thread-scope identifier.exact_thread_match=Falseleaves the thread dimension unconstrained.exact_thread_match=Truematches the providedthread_idexactly. Ifthread_id=None, it matches only records unscoped on the thread dimension. - user_id
str | None– Optional user and agent scope identifiers. The correspondingexact_*_match=Falseflag leaves that dimension unconstrained.exact_*_match=Truematches the provided ID exactly. If the ID isNone, it matches only records unscoped on that dimension. - agent_id
str | None– Optional user and agent scope identifiers. The correspondingexact_*_match=Falseflag leaves that dimension unconstrained.exact_*_match=Truematches the provided ID exactly. If the ID isNone, it matches only records unscoped on that dimension. - exact_user_match
bool– Whether each scope identifier must be matched exactly.Falseleaves that dimension unconstrained.Truematches the provided value exactly. If that value isNone, it matches only unscoped records on that dimension. - exact_agent_match
bool– Whether each scope identifier must be matched exactly.Falseleaves that dimension unconstrained.Truematches the provided value exactly. If that value isNone, it matches only unscoped records on that dimension. - exact_thread_match
bool– Whether each scope identifier must be matched exactly.Falseleaves that dimension unconstrained.Truematches the provided value exactly. If that value isNone, it matches only unscoped records on that dimension. - record_types
set[str] | None– Optional set of searchable record types to include. When omitted, the DB search covers messages, documents such as images, memory-table rows, and actor profiles. Image records contribute their description, actor profiles contribute theirinformationpayload, and message and memory rows contribute theircontentpayload. During search, profile record types use their actor identifier for the applicable scope dimension while the remaining scope dimensions behave asNone. - metadata_filter
dict[str, Any] | None– Optional metadata filter mapping. Entries inmetadata_filterare combined with AND semantics. Entries whose value is not a field-level operator dictionary use exact-match semantics: the requested key must exist in the stored metadata. Nested dictionaries are matched recursively. Scalar and list values are matched by exact equality; list order and length must also match. To test array membership, use a field-level operator dictionary such as{"tags": {"$array_contains": "prod"}}. A list operand for"$array_contains"means all listed values must be present;"$array_contains_any"means at least one listed value must be present. Use"$not"to negate another field-level expression at the same field, including an operator dictionary or raw exact-match value. Negated expressions match when the positive expression would fail, including missing fields; negated array membership also matches non-array fields. - include_invalid_results
bool– Whether results include memory-like records in the invalid status. Defaults toTrue. PassFalseto exclude them. - num_hops
int– Number of memory-link edges to follow from each direct memory result. Values from0through5are supported;0disables graph expansion. Expansion follows links in both directions. Linked records continue to obey the requested scope, metadata, record-type, and expiration filters. Direct message, document, and profile results remain in the result set but are not graph-expanded. - max_linked_results
int– Maximum linked memories across all hops attached to each direct result.0keeps direct results without linked context. Defaults to100.
- query
- Returns:
(record, distance)pairs sorted by increasing distance. The list may contain fewer thankentries. For a chunked query, the distance is derived from the reciprocal-rank-fusion score. - Return type: list[tuple[Record, float]]
- Raises:
- ValueError – If
kis less than1, if both or neither ofqueryandquery_vectorare provided, ifqueryis blank, if vector mode cannot resolve a query embedding, ifquery_vectoris invalid, or ifmetadata_filteris invalid. - TimeoutError – If graph expansion takes more than the allowed maximum time.
- ValueError – If
Examples
store.add(
["pizza preference"],
record_type="memory",
record_ids="mem-search-docs",
thread_ids="c-search-docs",
)
['mem-search-docs']
results = store.search(
"pizza",
1,
thread_id="c-search-docs",
exact_thread_match=True,
record_types={"memory"},
)
results[0][0].id
'mem-search-docs'
Filter on a scalar metadata value:
store.add(
["pizza release"],
record_type="memory",
record_ids="mem-search-meta-source-docs",
metadata={"source": "slack"},
)
['mem-search-meta-source-docs']
any(
record.id == "mem-search-meta-source-docs"
for record, _ in store.search(
"pizza",
k=3,
metadata_filter={"source": "slack"},
)
)
True
Filter on nested metadata:
store.add(
["pizza review"],
record_type="memory",
record_ids="mem-search-meta-review-docs",
metadata={"review": {"status": "open"}},
)
['mem-search-meta-review-docs']
any(
record.id == "mem-search-meta-review-docs"
for record, _ in store.search(
"pizza",
k=3,
metadata_filter={"review": {"status": "open"}},
)
)
True
Match a list value exactly, including order:
store.add(
["pizza tags"],
record_type="memory",
record_ids="mem-search-meta-tags-docs",
metadata={"tags": ["prod", "urgent"]},
)
['mem-search-meta-tags-docs']
any(
record.id == "mem-search-meta-tags-docs"
for record, _ in store.search(
"pizza",
k=3,
metadata_filter={"tags": ["prod", "urgent"]},
)
)
True
Filter when a metadata array contains a value:
any(
record.id == "mem-search-meta-tags-docs"
for record, _ in store.search(
"pizza",
k=3,
metadata_filter={"tags": {"$array_contains": "prod"}},
)
)
True
Combine multiple metadata conditions. A record must satisfy every key:
store.add(
["pizza rollout"],
record_type="memory",
record_ids="mem-search-meta-combined-docs",
metadata={
"source": "slack",
"review": {"status": "open"},
"tags": ["prod", "urgent"],
},
)
['mem-search-meta-combined-docs']
any(
record.id == "mem-search-meta-combined-docs"
for record, _ in store.search(
"pizza",
k=5,
metadata_filter={
"source": "slack",
"review": {"status": "open"},
"tags": ["prod", "urgent"],
},
)
)
True
method search_async (async)
Asynchronously search records by semantic similarity.
- Parameters:
- query
str | None– Same query text accepted bysearch. - k
int– Same maximum result count accepted bysearch. Explicit values must be at least1. - query_vector
list[float] | None– Same optional precomputed query embedding accepted bysearch. - thread_id
str | None– Same optional scope filters accepted bysearch. - user_id
str | None– Same optional scope filters accepted bysearch. - agent_id
str | None– Same optional scope filters accepted bysearch. - exact_user_match
bool– Same exact-match flags accepted bysearch. - exact_agent_match
bool– Same exact-match flags accepted bysearch. - exact_thread_match
bool– Same exact-match flags accepted bysearch. - record_types
set[str] | None– Same optional record-type filter accepted bysearch. - metadata_filter
dict[str, Any] | None– Same optional metadata filter accepted bysearch, including scalar, nested, exact-list, array-membership, and combined conditions such as{"source": "slack"},{"review": {"status": "open"}},{"tags": ["prod", "urgent"]}, and{"tags": {"$array_contains": "prod"}}. - include_invalid_results
bool– Same lifecycle-status result option accepted bysearch. - num_hops
int– Same graph-expansion depth accepted bysearch. - max_linked_results
int– Same per-direct-result linked-memory limit accepted bysearch.
- query
- Returns:
(record, distance)pairs returned by the underlyingsearchcall. - Return type: List[tuple[Record, float]]
- Raises:
ValueError – If
kis less than1.
method update
Update stored record content, search state, metadata, and timestamp values.
- Parameters:
- record_type
str– Record type label of the row being modified (for example"message","memory","guideline","fact","preference","user_profile", or"agent_profile") - record_id
str– Identifier of the stored row to update. - content
str | Mapping[str, object] | Sequence[MessageContent] | bytes | None– Canonical replacement content persisted in thecontentcolumn. For message records, pass""to clear the content while clearing any stored vector representation; explicitNoneis rejected. For memory-like records, passNoneto clear the stored text and embedding, and pass onlyNoneor omitted semantic arguments in the same call. When omitted, the existing content is left unchanged. Do not provide this together withtext. - index_text
str | list[str] | None– Optional semantic-only payload. When omitted,contentis used for semantic indexing. On hybrid-capable schemas this also becomes the stored search text used by Oracle’s text component. A string value may be chunked by the store; a list value is treated as caller-owned chunks and written as-is toRECORD_CHUNKS. When onlyembeddingis provided, the existing search text is reused. -
embedding
list[float] | ndarray | list[list[float] | ndarray] | None–Optional precomputed embedding vector or list of chunk embedding vectors. When local vector storage is configured, this is used directly and no embedder call is made. Pass
Noneto clear the stored embedding. A single vector represents the whole replacement text whencontentis provided, even when the configured chunker would split that text. Multiple chunk vectors are rejected when replacing text unlessindex_textis a chunk list. When onlyembeddingis provided, the embedding count must match the record’s existing chunk rows.In
SearchStrategy.VECTOR, vector search ranks against the stored embedding. InSearchStrategy.HYBRIDorSearchStrategy.KEYWORD, DB-backed search ranks through the stored search text and Oracle-managed text or hybrid index state, so update-time embeddings affect only any configured local vector storage, not that active search strategy. If this store was configured without local vector storage, provideindex_textinstead ofembeddingto update the text visible to those text-aware indexes. Text-only semantic updates may omitembeddingentirely in those modes. - metadata
dict[str, Any] | None– Optional metadata mapping serialized to JSON and stored inmetadata. Replacing imagecontentrequires"image_mime_type"with"image/png","image/jpeg", or"image/webp". The store uses this field to save the image, but does not return it as part of the record’s metadata. - timestamp
str | None– Optional new timestamp to save with the record. It represents when the record was created. When omitted, the existing timestamp is preserved. PassNoneto clear the saved timestamp and use the database creation time for futureTimeToLiveAnchor.CREATED_ATexpiration refreshes. Whenttl_anchorisTimeToLiveAnchor.TIMESTAMP, ISO-8601 timestamps without a timezone are treated as UTC. - ttl_days
int | None– Optional expiration refresh in days. Omit this argument together withttl_anchorto preserve the current expiration timestamp. PassNoneto useMemoryRetentionConfig.max_ttl_dayswhen the retention configuration sets one, or to clear expiration when it does not. Values aboveMemoryRetentionConfig.max_ttl_daysare clamped to that maximum with a warning. Refreshing expiration can make an expired record visible again if it has not been purged yet. - ttl_anchor
TimeToLiveAnchor– Optional time-to-live anchor for an expiration refresh. UseTimeToLiveAnchor.CREATED_ATto count from the stored creation time, orTimeToLiveAnchor.TIMESTAMPto count from the replacementtimestampsupplied in the same update, or the stored event timestamp whentimestampis omitted. Providingttl_anchorwithoutttl_daysrefreshes expiration using the schema’sMemoryRetentionConfig.default_ttl_days. Whenttl_anchoris omitted during a refresh, the store usesTimeToLiveAnchor.CREATED_AT. Timestamp-anchored refreshes require either a replacement ISO-8601 timestamp in the same call or an existing stored event timestamp in that format. ISO-8601 timestamps without a timezone are treated as UTC. - status
RecordStatus– Optional replacement lifecycle status for records. Omit it to preserve the current status. -
text
str | None–Deprecated alias for
content. PassNoneto clear the stored text and clear the stored embedding. Do not provide this together withcontent.Deprecated
Deprecated since version 26.8.0: This parameter was deprecated in 26.8.0 and will be removed in 27.1. Please use
contentinstead.
- record_type
- Returns:
Number of updated records (
0or1). A return value of0means no record was updated. - Return type: int
- Raises:
ValueError – If
record_typeis unsupported, if no update payload is provided, or if the semantic update arguments are incompatible.
Examples
store.add(["Original note"], record_type="memory", record_ids="mem-update-docs")
['mem-update-docs']
store.update("memory", "mem-update-docs", content="Updated note")
1
store.get("memory", "mem-update-docs").content
'Updated note'
method update_async (async)
Asynchronously update stored record content, embedding data, metadata, timestamp, or expiration.
- Parameters:
- record_type
str– Logical type of the record to update. - record_id
str– Identifier of the record to update. - content
str | Mapping[str, object] | Sequence[MessageContent] | bytes | None– Canonical replacement content. Formessagerecords, pass a string or an ordered sequence of text and image content parts; use""to replace the message with empty text. For memory-like records, stores may acceptNoneto clear the stored text and associated semantic state. Omit the argument to leave content unchanged. Do not provide this together withtext. - index_text
str | list[str] | None– Optional alternative semantic payload used to recompute or replace the stored search state without changing the persisted text. A string may be chunked internally by the store. A list of non-empty strings is treated as caller-owned chunks and must not be split again. Some implementations may also persist this separately as hybrid-search text. For animagerecord, this field replaces the persisted image description. - embedding
list[float] | ndarray | list[list[float] | ndarray] | None– Optional precomputed embedding vector or list of chunk embedding vectors. When provided, this is used directly and no embedder call is made. Multiple vectors require matchingindex_textchunk lists or existing stored chunk text rows. PassNoneto explicitly clear the stored embedding when the store supports it. Stores with text-aware indexing may also allow semantic updates without an embedder or explicit embedding. - metadata
dict[str, Any] | None– Optional replacement metadata mapping. PassNoneto clear metadata when the store supports it. Replacing imagecontentrequires"image_mime_type"in this mapping. The store uses this field to save the image, but does not return it as part of the record’s metadata. - timestamp
str | None– Optional new timestamp to save with the record. It represents when the record was created. Omit this argument to leave the stored timestamp unchanged. PassNoneto clear the saved timestamp and use the time the record was added to the store when the store supports it. - ttl_days
int | None– Optional expiration refresh in days. Omit this argument together withttl_anchorto preserve the current expiration timestamp. PassNoneto clear expiration. - ttl_anchor
TimeToLiveAnchor– Optional time-to-live anchor for an expiration refresh. UseTimeToLiveAnchor.CREATED_ATfor the record creation time orTimeToLiveAnchor.TIMESTAMPfor the replacementtimestampsupplied in the same update, or the stored event timestamp whentimestampis omitted. Providingttl_anchorwithoutttl_daysuses the store or schema default time-to-live duration. Whenttl_anchoris omitted during a refresh, implementations useTimeToLiveAnchor.CREATED_AT. - status
RecordStatus– Optional replacement lifecycle status for records. Omit it to preserve the current status. -
text
str | None–Deprecated alias for
content. PassNoneto explicitly clear the stored text when the store supports it. Do not provide this together withcontent.Deprecated
Deprecated since version 26.8.0: This parameter was deprecated in 26.8.0 and will be removed in 27.1. Please use
contentinstead.
- record_type
- Returns:
Number of updated records (
0or1). A return value of0means no record was updated. - Return type: int
- Raises: ValueError – If the update payload is invalid for the store, such as omitting every optional field or providing conflicting semantic arguments.
method update_relations
Update mutable relation fields and recalculate endpoint lifecycle state.
Omitted fields remain unchanged. Built-in memory link labels always retain their derived reverse label.
- Parameters:
- relation_ids
str | list[str]– Identifier or identifiers of the relations to update. - relation_types
str | list[str]– Optional replacement directed relation label or labels. - opposite_relation_types
str | list[str]– Optional replacement reverse label or labels for custom types. - timestamps
str | None | list[str | None]– Optional replacement timestamps. PassNoneto clear one. - metadata
dict[str, Any] | None | list[dict[str, Any] | None]– Optional replacement metadata. It replaces existing metadata.
- relation_ids
- Returns: Identifiers of relations that were updated.
- Return type: list[str]
Examples
store.update_relations("relation-id", relation_types="supports")
['relation-id']
method update_relations_async (async)
Asynchronously update mutable values on stored relations.
Omitted fields remain unchanged, except that changing to a built-in memory relation type replaces its reverse label with the fixed inverse. A DB-backed memory store also recalculates endpoint lifecycle states after a relation-type change.
- Parameters:
- relation_ids
str | list[str]– Identifier or identifiers of the relations to update. - relation_types
str | list[str]– Optional replacement directed relation label or labels. Omit this to preserve the stored labels. - opposite_relation_types
str | list[str]– Optional replacement reverse relation label or labels. Pass a label to replace it, or omit this argument to preserve it. - timestamps
str | None | list[str | None]– Optional replacement timestamp or timestamps. PassNoneto clear a stored timestamp. - metadata
dict[str, Any] | None | list[dict[str, Any] | None]– Optional replacement metadata object or objects. The supplied metadata replaces the stored object; it is not merged.
- relation_ids
- Returns: Identifiers of relations that were updated.
- Return type: list[str]
Examples
await store.update_relations_async(
"relation-id", relation_types="supports"
)
['relation-id']
Relations
OracleDBMemoryStore can store directed relations between memory-like
records (memory, fact, guideline, and preference). Use
add_relations(), get_relation(), list_relations(),
update_relations(), and delete_relations() when an integration needs the lower-level relation
API. The client and thread APIs provide link_records(),
update_record_link(), and delete_record_link() for supported memory
relation types.
To retrieve one relation, provide either relation_id by itself or the full
stored endpoint tuple: source record ID and type, target record ID and type,
and relation type. A partial tuple and a relation ID combined with any tuple
field are invalid because neither identifies the requested relation
unambiguously.
Use list_relations() to enumerate relations in creation order. Filter by
source or target record ID and type, or by directed relation label. It uses the
store’s normal safe list limit unless you pass limit=None. Its
metadata_filter uses the same exact-match, nested
object, array-membership, and negation semantics as list(); pass
metadata_filter=None to return only relations with no metadata.
Lifecycle relation types—supersedes, refines, and duplicates—mark
their target memory invalid while the link exists. Removing or changing the
last such link restores the target to valid status. Search APIs can exclude
invalid records with include_invalid_results=False.
class oracleagentmemory.apis.relations.RecordRelation
Bases: object
Describe one stored, directed relation between two records.
- Parameters:
- id
str– Stable identifier of the relation. - source_record_id
str– Identifier of the record at the stored source of the relation. - source_record_type
str– Logical type of the source record. - target_record_id
str– Identifier of the record at the stored target of the relation. - target_record_type
str– Logical type of the target record. - relation_type
str– Label whose meaning follows the stored source-to-target direction. - opposite_relation_type
str– Label used when traversal moves from target to source. - timestamp
str | None– Optional caller timestamp associated with the relation. - metadata
dict[str, Any] | None– Optional JSON-like metadata stored with the relation. - created_at
str– Database creation timestamp for the relation.
- id
Search Strategy
class oracleagentmemory.core.dbsearch.SearchStrategy
Bases: Enum
Search behavior for Oracle DB stores.
DB store initialization uses the selected strategy to choose the managed
schema search capability. VECTOR search stores local embeddings.
KEYWORD search stores searchable text and a text index. HYBRID
search stores searchable text plus Oracle-managed hybrid vector-index
state. The DB store validates this schema capability at startup so an
incompatible strategy does not silently return incomplete results.
VECTOR- Search by vector similarity only. The store embeds the query with the
configured embedder, or uses a caller-provided
query_vector, and ranks records by distance from the stored vectors. Use this with a DB schema configured for vector search. HYBRID- Search with Oracle’s managed hybrid index. Oracle combines text
matching over stored search text with vector ranking from the
in-database hybrid index. Use this when users may search by natural
language as well as exact identifiers, aliases, or product names. This
strategy requires the store’s main embedder to be an
OracleDBEmbedderso the managed index and store share one in-database model. KEYWORD- Search only by keyword/text matching over stored search text. This mode does not create local query embeddings and does not need an Oracle DB embedder. When opened against an existing hybrid schema, it can use the text branch of that hybrid index without creating a new hybrid index. Use this when exact identifiers, aliases, product names, or short phrases should drive retrieval without vector fusion.
HYBRID = ‘hybrid’
KEYWORD = ‘keyword’
VECTOR = ‘vector’
Search Index Sync Mode
class oracleagentmemory.core.dbsearch.SearchIndexSyncMode
Bases: Enum
Refresh behavior for managed DB search indexes.
This setting controls when Oracle makes new or changed search text visible
to DB-backed text-aware search. SearchStrategy.HYBRID uses Oracle’s
managed hybrid vector index. SearchStrategy.KEYWORD uses an Oracle
Text index. SearchStrategy.VECTOR does not use this setting.
ON_COMMIT- Refresh the index when the write transaction commits. This is the default and the simplest choice for most applications because records are searchable immediately after a successful write. It can add work to write transactions because the index is kept up to date right away.
MANUAL- Do not refresh the index automatically. New or updated records may not appear in keyword or hybrid search until you run the database-side index sync operation yourself. This is useful for bulk loads or maintenance windows where you want to control when refresh work runs.
AUTO- Let Oracle refresh the managed hybrid index asynchronously. Writes can
avoid the immediate refresh cost, but search results may lag behind
recent writes until Oracle completes the background refresh. This mode
is supported only with
SearchStrategy.HYBRID.
Warning: This setting controls ongoing maintenance after the managed search index exists. It does not make the first index build asynchronous. Creating a managed hybrid index over existing stored search text can be long-running because Oracle builds the managed hybrid-index state from that text.
AUTO = ‘auto’
MANUAL = ‘manual’
ON_COMMIT = ‘on_commit’
Time-to-Live
class oracleagentmemory.core.retention.MemoryRetentionConfig
Bases: object
Schema-level retention settings for Oracle DB-backed records.
- Parameters:
- default_ttl_days
int | None– Default time-to-live duration, in days. Leave asNOT_SET_MARKERto use the default ofNone(no maximum). - max_ttl_days
int | None– Optional maximum time-to-live duration, in days. Leave asNOT_SET_MARKERto use the default ofNone. PassNonefor no maximum. When set, this is a hard cap: writes that try to use a largerttl_daysvalue are clamped to this maximum with a warning, and write APIs that passttl_days=Noneuse this maximum instead of creating non-expiring records.
- default_ttl_days
class oracleagentmemory.apis.ttl.TimeToLiveAnchor
Bases: Enum
Anchor used to compute an expiration timestamp from a time-to-live duration.
CREATED_AT- Compute expiration from the record’s database creation timestamp.
This is the default when callers omit
ttl_anchor. TIMESTAMP- Compute expiration from the record’s stored event timestamp. Use this when a message or memory represents an older event and should expire relative to that event time instead of insert time.
CREATED_AT = ‘created_at’
TIMESTAMP = ‘timestamp’
Schema Policy
class oracleagentmemory.core.SchemaPolicy
Bases: str, Enum
Schema creation policy for Oracle DB stores.
REQUIRE_EXISTING
Validate that the full managed schema already exists and is up-to-date. Do not create or modify DB objects.
CREATE_IF_EMPTY
If no managed objects exist, bootstrap schema. If objects already exist, require a complete and up-to-date managed schema.
CREATE_IF_NECESSARY
Create missing managed objects and apply supported managed schema upgrades.
RECREATE
Drop and recreate all managed schema objects. This is destructive.
NO_CHECK
Skip managed schema validation and creation. Use this policy for an existing Deep Data Security-protected store while an end-user security context is active. A store opened under an end-user context requires an active context for each subsequent database operation. Other schema policies reject end-user contexts because schema lifecycle work must run through an administrative database identity.