Threads

This page presents the concrete Oracle thread handle together with the developer-facing message helper type.

Oracle Thread

class oracleagentmemory.core.OracleThread

Bases: IThread

Thread backed by an Oracle store.

This implementation embeds and stores both thread messages and manually added memories, then supports similarity search over all stored records.

Notes

Create a new OracleThread instance.

Examples

from oracleagentmemory.core import MemoryExtractionConfig, OracleAgentMemory
client = OracleAgentMemory(connection=db_pool, embedder=embedder)
thread = client.create_thread(
    thread_id="c4",
    llm=llm,
    memory_extraction_config=MemoryExtractionConfig(enable_context_summary=True),
)
len(thread.add_messages([{"role": "user", "content": "I love pizza."}]))
1

method add_image

Persist one image associated with this thread.

description is stored as the image’s searchable text. When it is omitted or None, an attached LLM generates a caption. Omitted scope values inherit this thread’s corresponding user, agent, and thread identifiers.

method add_image_async (async)

Persist one image associated with this thread asynchronously.

description is stored as the image’s searchable text. When it is omitted or None, an attached LLM generates a caption. Omitted scope values inherit this thread’s corresponding user, agent, and thread identifiers.

method add_memory

Add a manual memory entry and index it.

Examples

thread.add_memory("Remember this preference", memory_id="mem-thread-docs")
'mem-thread-docs'

method add_memory_async (async)

Add a manual memory entry and index it asynchronously.

Examples

import asyncio
asyncio.run(thread.add_memory_async(
    "Remember this preference", memory_id="mem-thread-docs-async"
))
'mem-thread-docs-async'

method add_messages

Add messages to the thread and index them.

In background extraction mode, this method returns after raw messages are inserted and due background extraction is attempted in the background.

Raw messages are stored before automatic extraction in either mode. If later extraction or derived-memory storage fails, the raw messages remain stored while derived memories or summary updates may be missing.

Notes

In MemoryExtractionMode.BACKGROUND, raw messages are persisted before extracted memories are stored. If background extraction does not queue, or if a configured queue-capacity wait reaches its timeout, the inserted raw messages remain stored and the call either continues without extracted memories or raises TimeoutError, depending on background_extraction_queue_full_behavior.

Examples

len(thread.add_messages([{"role": "user", "content": "Thread message from docs"}]))
1

method add_messages_async (async)

Asynchronously add messages to the thread and index them.

In background extraction mode, this method returns after raw messages are inserted and due background extraction is attempted in the background.

Raw messages are stored before automatic extraction in either mode. If later extraction or derived-memory storage fails, the raw messages remain stored while derived memories or summary updates may be missing.

In MemoryExtractionMode.BACKGROUND, raw messages are persisted before extracted memories are stored. If background extraction does not queue, or if a configured queue-capacity wait reaches its timeout, the inserted raw messages remain stored and the call either continues without extracted memories or raises TimeoutError, depending on background_extraction_queue_full_behavior.

method delete_image

Delete one image owned by this thread.

method delete_image_async (async)

Delete one image owned by this thread asynchronously.

method delete_memory

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

Notes

Before deleting the record, this method waits for earlier background extraction accepted for this thread through the attached agent memory component. It does not wait for work accepted after the wait begins or for work started by another component or process.

Examples

thread.delete_memory("456")
0

method delete_memory_async (async)

Delete a memory-like record (e.g., a memory, fact, preference, or guideline) from this exact thread by identifier asynchronously.

Notes

This method follows the background-extraction wait and concurrency behavior documented by delete_memory().

Examples

import asyncio
asyncio.run(thread.delete_memory_async("456"))
0

method delete_message

Delete a message record from this exact thread by identifier.

Notes

Before deleting the message, this method waits for earlier background extraction accepted for this thread through the attached agent memory component. It does not wait for work accepted after the wait begins or for work started by another component or process.

Deleting a message removes only the raw message record. Derived memories are not deleted because we do not yet track which extracted memories came from which message, so they may remain searchable or still affect context-card output. Use OracleAgentMemory.delete_thread() to delete the thread together with its associated messages and memories.

Examples

thread.delete_message("123")
0

method delete_message_async (async)

Delete a message record from this exact thread by identifier asynchronously.

Notes

This method follows the background-extraction wait and concurrency behavior documented by delete_message().

Deleting a message removes only the raw message record. Derived memories are not deleted because we do not yet track which extracted memories came from which message, so they may remain searchable or still affect context-card output. Use OracleAgentMemory.delete_thread() to delete the thread together with its associated messages and memories.

Examples

import asyncio
asyncio.run(thread.delete_message_async("123"))
0

Delete a thread-owned relation by ID or complete endpoint tuple.

Endpoint-tuple selectors must use the stored source-to-target orientation.

Examples

thread.delete_record_link(relation_id="relation-id")
1

Asynchronously delete a relation owned by this thread.

method get_context_card

Return a context-card object for the thread.

Prefer get_context_card_async when an LLM-backed implementation may perform remote network I/O.

Notes

This uses the thread’s default search scope with exact_thread_match=False, so relevant memories from other threads for the same user/agent may be included.

Examples

thread.add_memory("User likes pizza", memory_id="mem-context-docs")
'mem-context-docs'
len(thread.add_messages([{"role": "user", "content": "Tell me about pizza"}]))
1
"User likes pizza" in thread.get_context_card().content
True
card = thread.get_context_card(
    max_relevant_results=4,
    min_relevant_results_by_type={"memory": 1},
)
len(card.relevant_results or []) <= 4
True

method get_context_card_async (async)

Asynchronously return a context-card object for the thread.

Examples

import asyncio
card = asyncio.run(thread.get_context_card_async(
    min_relevant_results_by_type={"preference": 1, "guideline": 1},
))
len(card.relevant_results or []) <= 5
True

method get_message

Return one message owned by this thread.

Image parts are returned with their identifiers and descriptions by default. Pass included_image_ids to load bytes for selected image parts. Unrelated identifiers are ignored.

method get_message_async (async)

Return one thread-owned message asynchronously.

included_image_ids optionally selects attached image parts whose bytes should be loaded; omitted or None returns image metadata only.

method get_messages

Return stored messages for this thread.

Examples

len(thread.add_messages([{"role": "user", "content": "Stored message example"}]))
1
messages = thread.get_messages()
messages[-1].content
'Stored message example'

method get_messages_async (async)

Get the unprocessed messages from the thread as added with add_messages asynchronously.

Examples

import asyncio
message_ids = asyncio.run(thread.add_messages_async(
    [{"role": "user", "content": "Stored message example"}]
))
len(message_ids)
1
messages = asyncio.run(thread.get_messages_async())
messages[-1].content
'Stored message example'

method get_summary

Return a summary of the thread.

A whole-thread request reuses or refreshes the durable summary. A request with except_last summarizes that prefix without changing the durable whole-thread summary.

Prefer get_summary_async when an LLM-backed implementation may perform remote network I/O.

Examples

len(thread.add_messages([{"role": "assistant", "content": "Summary source message"}]))
1
summary = thread.get_summary()
bool(summary.content)
True

method get_summary_async (async)

Asynchronously return a summary of the thread.

A whole-thread request reuses or refreshes the durable summary. A request with except_last summarizes that prefix without changing the durable whole-thread summary.

Create a directed relation between two records owned by this thread.

Currently, both endpoints must be memory-like records: "memory", "fact", "guideline", or "preference". Built-in relation types are "supersedes" ("is_superseded_by"), "contradicts", "refines" ("is_refined_by"), "supports" ("is_supported_by"), and "duplicates". "contradicts" and "duplicates" use the same label in reverse.

Both endpoints must belong to this exact thread. Only one orientation can be stored for an endpoint pair. opposite_relation_type names the relation when traversing from target to source; for example, new "supersedes" old becomes old "is_superseded_by" new in that direction.

Examples

thread.link_records(
    "fact-1", "fact", "memory-1", "memory", "supports"
)
'relation-id'

Asynchronously create a relation between records owned by this thread.

Currently, both endpoints must be memory-like records: "memory", "fact", "guideline", or "preference". Built-in relation types are "supersedes" ("is_superseded_by"), "contradicts", "refines" ("is_refined_by"), "supports" ("is_supported_by"), and "duplicates". "contradicts" and "duplicates" use the same label in reverse.

method list_images

List image records owned by this thread.

Returned records contain image metadata by default. Raw bytes are loaded only when include_bytes=True and image_id is provided.

method list_images_async (async)

List image records owned by this thread asynchronously.

Returned records contain image metadata by default. Raw bytes are loaded only when include_bytes=True and image_id is provided. This thread’s scope is applied automatically.

Search synchronously for records relevant to a query.

Notes

Omitted scope fields inherit this thread’s default search scope: exact user and agent matching plus this thread’s current user_id, agent_id, and thread_id. The default thread search intentionally leaves exact_thread_match=False, so it may return relevant records from other threads for the same user/agent. Pass exact_thread_match=True to restrict results to the current thread. Explicit None scope values still follow the resolved exact-match rules: exact_*_match=False leaves that dimension unconstrained, while exact_*_match=True matches only stored None values.

Explicit max_results values must be at least 1; omitting the argument uses the default value of 10. This is an upper bound: the call may return fewer than max_results results when filters are too restrictive, when fewer matching records exist, or because of implementation-specific search behavior.

method search_async (async)

Search asynchronously for records relevant to a query.

Notes

Omitted scope fields inherit this thread’s default search scope: exact user and agent matching plus this thread’s current user_id, agent_id, and thread_id. The default thread search intentionally leaves exact_thread_match=False, so it may return relevant records from other threads for the same user/agent. Pass exact_thread_match=True to restrict results to the current thread. Explicit None scope values still follow the resolved exact-match rules: exact_*_match=False leaves that dimension unconstrained, while exact_*_match=True matches only stored None values.

Explicit max_results values must be at least 1; omitting the argument uses the default value of 10. This is an upper bound: the call may return fewer than max_results results when filters are too restrictive, when fewer matching records exist, or because of implementation-specific search behavior.

method update_image

Update one image owned by this thread.

Omit image to preserve the existing bytes. If image is provided, mime_type must be provided with it. Omit description to preserve the existing description. Pass None to generate a new description with the configured LLM; a non-null description replaces it directly. Expiration for an image attached to a message must be changed through update_message().

method update_image_async (async)

Update one image owned by this thread asynchronously.

Omit image to preserve the existing bytes. If image is provided, mime_type must be provided with it. Omit description to preserve the existing description. Pass None to generate a new description with the configured LLM; a non-null description replaces it directly. Metadata, timestamp, and expiration settings are updated when supplied. Expiration for an image attached to a message must be changed through update_message_async().

method update_memory

Update a memory-like record owned by this exact thread.

method update_memory_async (async)

Update a memory-like record owned by this exact thread asynchronously.

Examples

import asyncio
memory_id = asyncio.run(thread.add_memory_async("Original memory"))
(
    asyncio.run(thread.update_memory_async(
        memory_id, content="Updated memory"
    ))
    == memory_id
)
True

method update_message

Update a raw message record owned by this exact thread.

Notes

Omitted fields are preserved from the stored record. Stored role and timestamp remain unchanged. Editing content updates the raw message history and, when automatic extraction is enabled, can cause the SDK to re-extract memories from the edited message and earlier history. In INLINE mode, that extraction completes before this method returns. In BACKGROUND mode, this method returns after the raw message update succeeds and background extraction is attempted. This follow-up work does not affect the normal extraction frequency used by later add_messages() calls. Existing extracted memories remain in place while newly extracted memories from the edited content may be added. Because the raw message update and any later extracted-memory writes do not happen atomically, extracted memories can still reflect the earlier message content if the background work does not queue, if a configured queue-capacity wait reaches its timeout, or if later extraction work fails. Also, note that existing extracted memories keep their original expiration when a source message’s TTL changes.

Examples

message_id = thread.add_messages([{"role": "user", "content": "Draft message"}])[0]
thread.update_message(message_id, content="Edited message") == message_id
True

method update_message_async (async)

Update a raw message record owned by this exact thread asynchronously.

Notes

Omitted fields are preserved from the stored record. Stored role and timestamp remain unchanged. Editing content updates the raw message history and, when automatic extraction is enabled, can cause the SDK to re-extract memories from the edited message and earlier history. In INLINE mode, that extraction completes before this method returns. In BACKGROUND mode, this method returns after the raw message update succeeds and background extraction is attempted. This follow-up work does not affect the normal extraction frequency used by later add_messages() calls. Existing extracted memories remain in place while newly extracted memories from the edited content may be added. Because the raw message update and any later extracted-memory writes do not happen atomically, extracted memories can still reflect the earlier message content if the background work does not queue, if a configured queue-capacity wait reaches its timeout, or if later extraction work fails. Also, note that existing extracted memories keep their original expiration when a source message’s TTL changes.

Examples

import asyncio
message_ids = asyncio.run(thread.add_messages_async(
    [{"role": "user", "content": "Draft message"}]
))
(
    asyncio.run(thread.update_message_async(
        message_ids[0], content="Edited message"
    ))
    == message_ids[0]
)
True

Update a relation whose endpoints are owned by this thread.

Omitted values are preserved. When relation_type changes to a built-in memory relation type, its fixed reverse label replaces opposite_relation_type.

Examples

thread.update_record_link("relation-id", relation_type="supports")
1

Asynchronously update a relation whose endpoints belong to this thread.

method wait_for_memory_extraction

Wait for earlier background memory extraction for this thread.

This method waits for background extraction started by earlier add_messages(), add_messages_async(), update_message(), or update_message_async() calls on this thread through the same agent memory component. If one of those calls is already finishing, this method includes the extraction it starts before waiting.

The method does not wait for extraction started after this wait begins, for extraction started by a different agent memory component, or for extraction running in another process. Extraction failures count as finished for this wait.

Examples

thread.wait_for_memory_extraction(timeout=10)

method wait_for_memory_extraction_async (async)

Asynchronously wait for earlier background memory extraction.

This method follows the same behavior as wait_for_memory_extraction().

Examples

import asyncio
asyncio.run(thread.wait_for_memory_extraction_async(timeout=10))

Note: delete_message() deletes only the raw message row. Derived memories may still be searchable or appear in context cards. Use OracleAgentMemory.delete_thread() to delete the thread together with its associated messages and memories. Message and memory deletion through a thread handle waits for earlier background extraction already accepted by the attached client for that thread. This is not a global concurrency barrier for other client instances, processes, or work accepted after the wait begins.

Messages and message contents

class oracleagentmemory.apis.message.Message

Bases: object

The in-memory message shared by threads and LLM adapters.

class oracleagentmemory.apis.message.MessageContent

Bases: ABC

Base class for structured message content.

class oracleagentmemory.apis.message.TextContent

Bases: MessageContent

A text part in a multimodal message.

class oracleagentmemory.apis.message.ImageContent

Bases: MessageContent

An image part in a multimodal message.

class oracleagentmemory.apis.message.ImageMimeType

Bases: str, Enum

MIME types supported for image content.

Animated PNG and WebP are not supported.

JPEG = ‘image/jpeg’

PNG = ‘image/png’

WEBP = ‘image/webp’

Context Cards

class oracleagentmemory.apis.contextcard.ContextCard

Bases: ABC

Abstract context-card object returned by thread APIs.

property content (abstract)

class oracleagentmemory.core.contextcard.OracleContextCard

Bases: ContextCard

Context card returned by an Oracle thread.

property content

Examples

card = OracleContextCard(summary="ctx")
"<summary>" in card.content and "ctx" in card.content
True

property formatted_content

Examples

OracleContextCard(summary="").formatted_content
''
card = OracleContextCard(summary="ctx", topics=["travel"])
"<topics>" in card.formatted_content
True

Summaries

class oracleagentmemory.apis.summary.Summary

Bases: ABC

Abstract thread-summary object returned by thread APIs.

property content (abstract)

class oracleagentmemory.core.summary.OracleSummary

Bases: Summary

Summary returned by an Oracle thread.

Examples

summary = OracleSummary(content="Plan the Rome itinerary.")
summary.content
'Plan the Rome itinerary.'
str(summary)
'Plan the Rome itinerary.'

property content

Examples

OracleSummary(content="Keep the tea preference in mind.").content
'Keep the tea preference in mind.'

property formatted_content

Examples

OracleSummary(content="Thread recap").formatted_content
'Thread recap'