Agent Memory
By default, each call to your agent is stateless: the agent only sees the message you just sent. That's fine for one-shot tasks (classification, extraction, single answers) but breaks down for anything conversational.
DYPAI includes built-in memory so the agent can remember what was said earlier — either within a single conversation or across every conversation a user has ever had.
Memory modes
| Parameter | Type | Description |
|---|---|---|
none | default | Stateless. Every request is independent. Good for one-shot queries. |
session | mode | Memory keyed by session_id. One chat window = one session. Use for standard chatbots. |
user | mode | Memory scoped to the authenticated user. The agent remembers the user across all their sessions. |
Pick the mode in the agent node's Memory field.
How session memory works
When memory_mode = session:
- Your frontend generates (or stores) a
session_idfor each conversation. - Every time the user sends a message, you pass the same
session_id. - The agent loads the previous messages for that session, adds the new user message, calls the model, and persists the new assistant reply.
A new session_id = a fresh conversation, no memory carried over. The SDK's useChat() hook handles this automatically.
How user memory works
When memory_mode = user:
- No
session_idis needed. The agent uses the authenticated user's ID from the JWT. - Every message from that user anywhere in your app is merged into one rolling history.
- Good for "personal assistant" experiences where you want continuity across days and devices.
User memory requires auth
User-scoped memory needs an authenticated caller. If your agent endpoint is public, user memory falls back to stateless.
The memory window
Loading all messages forever would blow up the model's context window and your token bill. DYPAI controls this with two knobs:
| Parameter | Type | Description |
|---|---|---|
memory_window | number (default 20) | Max messages loaded from history. Older messages are dropped. |
memory_max_tokens | number (default 4000) | Hard cap on tokens loaded. If adding another message would exceed this, it's dropped. Prevents long conversations from filling the entire context window. |
The two limits are applied together — whichever triggers first wins. The agent always sees the most recent messages.
Where memory is stored
Memory lives in your own project database, in two system tables:
system.ai_chats— one row per chat session, withid,user_id,endpoint_id, and metadatasystem.ai_messages— one row per message, withchat_id,role, andparts(the full Vercel AI SDK message format)
These tables are created automatically the first time an agent with memory runs. You can query them with execute_sql like any other table — useful for building chat history UIs or moderation dashboards.
Listing past conversations
The SDK gives you a hook to list a user's past sessions. useChatList takes an options object (not a positional string):
import { useChatList } from '@dypai-ai/client-sdk/react'
function ConversationsSidebar() {
const { chats, isLoading, error, deleteChat, renameChat, refetch } =
useChatList({ endpointId: '<endpoint_id>', limit: 50 })
return (
<ul>
{chats.map(c => (
<li key={c.id}>
<a href={`/chat/${c.id}`}>{c.title ?? 'Untitled'}</a>
</li>
))}
</ul>
)
}
useChatList({ endpointId, limit, enabled }) returns:
chats— the list of conversationsisLoading/error— load statedeleteChat(chatId)— delete a conversationrenameChat(chatId, title)— rename a conversationrefetch()— reload the list
Combined with useChat('endpoint', { id }), this gives you the classic ChatGPT-style "sidebar with all my past conversations" for free. (The resume option is id, not sessionId.)
Clearing memory
Users occasionally want a fresh start. Your options, easiest first:
- Delete a conversation (recommended): call
deleteChat(chatId)fromuseChatList. It removes the chat and its messages — no backend code needed. Wire it to a "Delete this conversation" button. - New conversation: start a fresh chat with
useChat('endpoint', { id: newId })(or noid). The old conversation stays stored but isn't loaded. - Advanced (optional): delete the row directly from
system.ai_chatswith SQL (cascades to messages) — useful for bulk cleanup or admin tooling.
Memory and tool calls
Tool calls are stored as part of the conversation. When memory is loaded, the model sees:
- User messages
- Assistant replies
- Tool calls the assistant made
- Tool results returned
This means the agent remembers what data it fetched earlier and doesn't have to call the same tool twice. If the user asks "what were my orders again?", the agent can answer from memory without re-querying your database.
Privacy notes
- Memory is scoped per project — agents in one project can't see conversations in another.
- User memory is scoped per user — users can't see each other's history.
- Memory data is stored in your project database alongside your regular tables. Your existing backups, access controls, and data deletion flows apply.
- For GDPR-style deletion, simply delete rows from
system.ai_chatsfor the relevant user.