Use Agent Memory with WayFlow

In this article, you will learn how to connect Agent Memory to a WayFlow agent so the agent can reuse durable facts across sessions.

Tip: For package setup, see Get Started with Agent Memory. If you need a local Oracle AI Database for this example, see Run Oracle AI Database Locally. To learn more about WayFlow, see https://github.com/oracle/wayflow.

Configure Agent Memory and WayFlow

Create an Agent Memory thread for the user, expose a search_memory tool to WayFlow, and construct the WayFlow Agent with an OpenAIModel. The search_memory tool queries the Agent Memory API by user and agent ID so it can recover durable facts from prior sessions instead of being limited to the current thread. The Agent Memory client also uses its own LLM to periodically extract durable memories from recent thread messages, while the WayFlow Agent continues to use its own OpenAIModel for replies and tool calls.

from oracleagentmemory.core.embedders.embedder import Embedder
from oracleagentmemory.core.llms.llm import Llm
from oracleagentmemory.core.oracleagentmemory import OracleAgentMemory
from wayflowcore.agent import Agent
from wayflowcore.models import OpenAIModel
from wayflowcore.tools import tool

embedder = Embedder(
    model="YOUR_EMBEDDING_MODEL",
    api_base="YOUR_EMBEDDING_API_BASE",
    api_key="YOUR_EMBEDDING_API_KEY",
)
llm = Llm(
    model="gpt-4.1-mini",
    api_key="YOUR_OPENAI_API_KEY",
)
db_pool = ...  #an oracledb connection or connection pool
wayflow_llm = OpenAIModel(
    model_id="gpt-4.1-mini",
    api_key="YOUR_OPENAI_API_KEY",
)


#Keep these identifiers stable for the same assistant and end user so memory
#is scoped consistently across threads and sessions.
agent_id = "support_agent"
user_id = "user_123"
memory = OracleAgentMemory(
    connection=db_pool,
    embedder=embedder,
    llm=llm,
)
memory_thread = memory.create_thread(
    thread_id="wayflow_memory_demo",
    user_id=user_id,
    agent_id=agent_id,
)

from typing import Annotated


@tool
def search_memory(
    query: Annotated[str, "Question to search in Oracle Agent Memory"],
) -> Annotated[str, "Top matching memory content"]:
    """Search Oracle Agent Memory for durable user facts relevant to the current request."""
    results = memory.search(
        query=query,
        user_id=user_id,
        agent_id=agent_id,
        max_results=1,
        record_types=["memory"],
    )
    if not results:
        return "No relevant memory found."
    return results[0].content

assistant = Agent(
    llm=wayflow_llm,
    agent_id=agent_id,
    custom_instruction=(
        "You are a support agent. When the user asks about durable facts from "
        "prior sessions, call the search_memory tool before answering."
    ),
    tools=[search_memory],
)

Persist User Context After a Session

After each WayFlow session, append the exchanged messages to Agent Memory and store any durable fact that should be reused later.

session_1 = assistant.start_conversation()
user_message = (
    "I am John, a Python developer and I need help debugging a payment service."
)
session_1.append_user_message(user_message)
session_1.execute()
assistant_reply = session_1.get_last_message().content

print(assistant_reply)
#I can help with that. What error are you seeing?

#add_messages will add messages to the DB and extract memories automatically
memory_thread.add_messages(
    [
        {"role": "user", "content": user_message},
        {"role": "assistant", "content": assistant_reply},
    ]
)
#add_memory adds memory to the DB
memory_thread.add_memory("The user is John, a Python developer.")

Reuse Memory in a New WayFlow Session

When a later session starts, reopen the same Agent Memory thread and let the WayFlow agent call search_memory to recover prior user context.

memory_thread = memory.get_thread("wayflow_memory_demo")
assistant = Agent(
    llm=wayflow_llm,
    agent_id=agent_id,
    custom_instruction=(
        "You are a support agent. When the user asks about durable facts from "
        "prior sessions, call the search_memory tool before answering."
    ),
    tools=[search_memory],
)

session_2 = assistant.start_conversation()
session_2.append_user_message("Who am I?")
session_2.execute()
remembered_reply = session_2.get_last_message().content

print(remembered_reply)

Output:

The user is John, a Python developer.

Advanced Use

For tighter integration, you can register a WayFlow event listener that buffers ConversationMessageAddedEvent` entries and writes them to Agent Memory at the end of an execution. This keeps the Agent Memory update path decoupled from your main thread code while still persisting the final exchanged messages.

from wayflowcore.events.event import ConversationMessageAddedEvent
from wayflowcore.events.eventlistener import GenericEventListener, register_event_listeners

pending_messages: list[dict[str, str]] = []


def _buffer_thread_message(event: ConversationMessageAddedEvent) -> None:
    if event.streamed:
        return
    pending_messages.append(
        {
            "role": event.message.role,
            "content": event.message.content,
        }
    )


message_listener = GenericEventListener(
    [ConversationMessageAddedEvent],
    _buffer_thread_message,
)

with register_event_listeners([message_listener]):
    session_3 = assistant.start_conversation()
    session_3.append_user_message("Please remember that I prefer concise code reviews.")
    session_3.execute()

if pending_messages:
    memory_thread.add_messages(pending_messages)

Disable Automatic Extraction

If you only want to persist messages and add durable memories manually, create the Agent Memory client with extract_memories=False and insert the durable memory rows yourself.

manual_memory = OracleAgentMemory(
    connection=db_pool,
    embedder=embedder,
    extract_memories=False,
)
manual_memory_thread = manual_memory.create_thread(
    thread_id="wayflow_manual_memory_demo",
    user_id=user_id,
    agent_id=agent_id,
)
manual_memory_thread.add_messages(
    [
        {
            "role": "user",
            "content": "Please remember that I prefer concise code reviews.",
        },
        {
            "role": "assistant",
            "content": "Understood. I will keep responses concise.",
        },
    ]
)
manual_memory_thread.add_memory("The user prefers concise code reviews.")

Conclusion

In this article we learned how to connect Agent Memory to a WayFlow agent, persist exchanged messages and durable memories after each session, and reuse prior user context in later executions.

Tip: Having learned how to integrate Agent Memory with WayFlow, you may also be interested in Integrate Agent Memory with LangGraph.

Full Code

#Copyright © 2026 Oracle and/or its affiliates.
#isort:skip_file
#fmt: off
#Agent Memory Code Example - Integration with WayFlow
#-----------------------------------------------------

#How to use:
#Create a new Python virtual environment and install the latest oracleagentmemory version.

#You can now run the script
#1. As a Python file:
#```bash
#python integration_with_wayflow.py
#```
#2. As a Notebook (in VSCode):
#When viewing the file,
#- press the keys Ctrl + Enter to run the selected cell
#- or Shift + Enter to run the selected cell and move to the cell below


##Configure Oracle Memory and WayFlow

#%%
from oracleagentmemory.core.embedders.embedder import Embedder
from oracleagentmemory.core.llms.llm import Llm
from oracleagentmemory.core.oracleagentmemory import OracleAgentMemory
from wayflowcore.agent import Agent
from wayflowcore.models import OpenAIModel
from wayflowcore.tools import tool

embedder = Embedder(
    model="YOUR_EMBEDDING_MODEL",
    api_base="YOUR_EMBEDDING_API_BASE",
    api_key="YOUR_EMBEDDING_API_KEY",
)
llm = Llm(
    model="gpt-4.1-mini",
    api_key="YOUR_OPENAI_API_KEY",
)
db_pool = ...  #an oracledb connection or connection pool
wayflow_llm = OpenAIModel(
    model_id="gpt-4.1-mini",
    api_key="YOUR_OPENAI_API_KEY",
)

#Keep these identifiers stable for the same assistant and end user so memory
#is scoped consistently across threads and sessions.
agent_id = "support_agent"
user_id = "user_123"
memory = OracleAgentMemory(
    connection=db_pool,
    embedder=embedder,
    llm=llm,
)
memory_thread = memory.create_thread(
    thread_id="wayflow_memory_demo",
    user_id=user_id,
    agent_id=agent_id,
)

from typing import Annotated


@tool
def search_memory(
    query: Annotated[str, "Question to search in Oracle Agent Memory"],
) -> Annotated[str, "Top matching memory content"]:
    """Search Oracle Agent Memory for durable user facts relevant to the current request."""
    results = memory.search(
        query=query,
        user_id=user_id,
        agent_id=agent_id,
        max_results=1,
        record_types=["memory"],
    )
    if not results:
        return "No relevant memory found."
    return results[0].content

assistant = Agent(
    llm=wayflow_llm,
    agent_id=agent_id,
    custom_instruction=(
        "You are a support agent. When the user asks about durable facts from "
        "prior sessions, call the search_memory tool before answering."
    ),
    tools=[search_memory],
)


##Persist user context after a session

#%%
session_1 = assistant.start_conversation()
user_message = (
    "I am John, a Python developer and I need help debugging a payment service."
)
session_1.append_user_message(user_message)
session_1.execute()
assistant_reply = session_1.get_last_message().content

print(assistant_reply)
#I can help with that. What error are you seeing?

memory_thread.add_messages(
    [
        {"role": "user", "content": user_message},
        {"role": "assistant", "content": assistant_reply},
    ]
)
memory_thread.add_memory("The user is John, a Python developer.")


##Reuse memory in a new WayFlow session

#%%
memory_thread = memory.get_thread("wayflow_memory_demo")
assistant = Agent(
    llm=wayflow_llm,
    agent_id=agent_id,
    custom_instruction=(
        "You are a support agent. When the user asks about durable facts from "
        "prior sessions, call the search_memory tool before answering."
    ),
    tools=[search_memory],
)

session_2 = assistant.start_conversation()
session_2.append_user_message("Who am I?")
session_2.execute()
remembered_reply = session_2.get_last_message().content

print(remembered_reply)
#The user is John, a Python developer.


##Advanced use event listeners

#%%
from wayflowcore.events.event import ConversationMessageAddedEvent
from wayflowcore.events.eventlistener import GenericEventListener, register_event_listeners

pending_messages: list[dict[str, str]] = []


def _buffer_thread_message(event: ConversationMessageAddedEvent) -> None:
    if event.streamed:
        return
    pending_messages.append(
        {
            "role": event.message.role,
            "content": event.message.content,
        }
    )


message_listener = GenericEventListener(
    [ConversationMessageAddedEvent],
    _buffer_thread_message,
)

with register_event_listeners([message_listener]):
    session_3 = assistant.start_conversation()
    session_3.append_user_message("Please remember that I prefer concise code reviews.")
    session_3.execute()

if pending_messages:
    memory_thread.add_messages(pending_messages)


##Disable automatic memory extraction

#%%
manual_memory = OracleAgentMemory(
    connection=db_pool,
    embedder=embedder,
    extract_memories=False,
)
manual_memory_thread = manual_memory.create_thread(
    thread_id="wayflow_manual_memory_demo",
    user_id=user_id,
    agent_id=agent_id,
)
manual_memory_thread.add_messages(
    [
        {
            "role": "user",
            "content": "Please remember that I prefer concise code reviews.",
        },
        {
            "role": "assistant",
            "content": "Understood. I will keep responses concise.",
        },
    ]
)
manual_memory_thread.add_memory("The user prefers concise code reviews.")