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:
import { useChatList } from '@dypai-ai/client-sdk/react'
function ConversationsSidebar() {
const { chats, isLoading } = useChatList('my_agent_endpoint')
return (
<ul>
{chats.map(c => (
<li key={c.id}>
<a href={`/chat/${c.id}`}>{c.title ?? 'Untitled'}</a>
</li>
))}
</ul>
)
}
Combined with useChat(endpoint, { sessionId }), this gives you the classic ChatGPT-style "sidebar with all my past conversations" for free.
Clearing memory
Users occasionally want a fresh start. You have two options:
- New session: Generate a new
session_idon the frontend. The old conversation stays stored but isn't loaded. - Delete: Delete the row from
system.ai_chats(cascades to messages). Build a "delete this conversation" button that calls adelete_chatendpoint you've created.
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.