Use Agent Memory with WayFlow
WayFlow, a library for building AI assistants, orchestrates agent responses and tool calls during a session. However, many applications also need to preserve user context after the session or conversation ends. Oracle AI Agent Memory stores this long-lived context so a later WayFlow conversation can retrieve and use it.
In this guide, you will learn how to connect Agent Memory to a WayFlow agent, allowing the agent to reuse information across sessions.
Note: Use this integration when an agent needs to remember information beyond the current session, such as user preferences, support details, or standing instructions. Use WayFlow alone when the context only matters during the current session or conversation.
Hint: For package setup, see the Get Started with Agent Memory. To learn how to set up a local Oracle AI Database for this example, follow Run Oracle AI Database locally. To learn more about WayFlow, see https://github.com/oracle/wayflow.
Configure Agent Memory and WayFlow
Create an Oracle 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 Oracle 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 Oracle 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.
import oracledb
from oracleagentmemory.core import MemoryExtractionConfig, OracleAgentMemory, SchemaPolicy
from oracleagentmemory.core.embedders.embedder import Embedder
from oracleagentmemory.core.llms.llm import Llm
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 = oracledb.SessionPool(
user="YOUR DB USER",
password="YOUR DB PASSWORD",
dsn="localhost:1521/...",
)
memory_store_id = "T_WAYFLOW"
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,
schema_policy=SchemaPolicy.CREATE_IF_NECESSARY,
memory_store_id=memory_store_id,
)
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],
)
| API Reference: OracleAgentMemory | OracleThread |
Persist User Context After a Session
After each WayFlow session, append the exchanged messages to Oracle 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 Oracle 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)
#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 Oracle Agent Memory at
the end of an execution. This keeps the Oracle 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 Oracle Agent Memory client with
memory_extraction_config=MemoryExtractionConfig(extract_memories=False)
and insert the durable memory rows yourself.
manual_memory = OracleAgentMemory(
connection=db_pool,
embedder=embedder,
schema_policy=SchemaPolicy.CREATE_IF_NECESSARY,
memory_store_id=memory_store_id,
memory_extraction_config=MemoryExtractionConfig(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 guide we learned how to connect Oracle Agent Memory to a WayFlow agent, persist exchanged messages and durable memories after each session, and reuse prior user context in later executions.
→ Having learned how to use Oracle Agent Memory with WayFlow, you may also be interested in Use Oracle Agent Memory with LangGraph.
Full Code
#Copyright © 2026 Oracle and/or its affiliates.
#This software is under the Apache License 2.0
#(LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0) or Universal Permissive License
#(UPL) 1.0 (LICENSE-UPL or https://oss.oracle.com/licenses/upl), at your option.
#Oracle Agent Memory Code Example - Integration with WayFlow
#-----------------------------------------------------------
##Configure Oracle Memory and WayFlow
import oracledb
from oracleagentmemory.core import MemoryExtractionConfig, OracleAgentMemory, SchemaPolicy
from oracleagentmemory.core.embedders.embedder import Embedder
from oracleagentmemory.core.llms.llm import Llm
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 = oracledb.SessionPool(
user="YOUR DB USER",
password="YOUR DB PASSWORD",
dsn="localhost:1521/...",
)
memory_store_id = "T_WAYFLOW"
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,
schema_policy=SchemaPolicy.CREATE_IF_NECESSARY,
memory_store_id=memory_store_id,
)
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?
#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
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,
schema_policy=SchemaPolicy.CREATE_IF_NECESSARY,
memory_store_id=memory_store_id,
memory_extraction_config=MemoryExtractionConfig(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.")