Skip to content

Commit 5fa2641

Browse files
icecrasher321waleedlatif1
authored andcommitted
fix memory
1 parent 0b25574 commit 5fa2641

File tree

10 files changed

+428
-839
lines changed

10 files changed

+428
-839
lines changed
Lines changed: 36 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
title: Memory
3-
description: Add memory store
3+
description: Store and retrieve conversation history
44
---
55

66
import { BlockInfoCard } from "@/components/ui/block-info-card"
@@ -10,100 +10,94 @@ import { BlockInfoCard } from "@/components/ui/block-info-card"
1010
color="#F64F9E"
1111
/>
1212

13-
## Usage Instructions
14-
15-
Integrate Memory into the workflow. Can add, get a memory, get all memories, and delete memories.
13+
## Overview
1614

15+
The Memory block stores conversation history for agents. Each memory is identified by a `conversationId` that you provide. Multiple agents can share the same memory by using the same `conversationId`.
1716

17+
Memory stores only user and assistant messages. System messages are not stored—they are configured in the Agent block and prefixed at runtime.
1818

1919
## Tools
2020

2121
### `memory_add`
2222

23-
Add a new memory to the database or append to existing memory with the same ID.
23+
Add a message to memory. Creates a new memory if the `conversationId` doesn't exist, or appends to existing memory.
2424

2525
#### Input
2626

2727
| Parameter | Type | Required | Description |
2828
| --------- | ---- | -------- | ----------- |
29-
| `conversationId` | string | No | Conversation identifier \(e.g., user-123, session-abc\). If a memory with this conversationId already exists for this block, the new message will be appended to it. |
30-
| `id` | string | No | Legacy parameter for conversation identifier. Use conversationId instead. Provided for backwards compatibility. |
31-
| `role` | string | Yes | Role for agent memory \(user, assistant, or system\) |
32-
| `content` | string | Yes | Content for agent memory |
33-
| `blockId` | string | No | Optional block ID. If not provided, uses the current block ID from execution context, or defaults to "default". |
29+
| `conversationId` | string | Yes | Unique identifier for the conversation (e.g., `user-123`, `session-abc`) |
30+
| `role` | string | Yes | Message role: `user` or `assistant` |
31+
| `content` | string | Yes | Message content |
3432

3533
#### Output
3634

3735
| Parameter | Type | Description |
3836
| --------- | ---- | ----------- |
39-
| `success` | boolean | Whether the memory was added successfully |
40-
| `memories` | array | Array of memory objects including the new or updated memory |
41-
| `error` | string | Error message if operation failed |
37+
| `success` | boolean | Whether the operation succeeded |
38+
| `memories` | array | Updated memory array |
39+
| `error` | string | Error message if failed |
4240

4341
### `memory_get`
4442

45-
Retrieve memory by conversationId, blockId, blockName, or a combination. Returns all matching memories.
43+
Retrieve memory by conversation ID.
4644

4745
#### Input
4846

4947
| Parameter | Type | Required | Description |
5048
| --------- | ---- | -------- | ----------- |
51-
| `conversationId` | string | No | Conversation identifier \(e.g., user-123, session-abc\). If provided alone, returns all memories for this conversation across all blocks. |
52-
| `id` | string | No | Legacy parameter for conversation identifier. Use conversationId instead. Provided for backwards compatibility. |
53-
| `blockId` | string | No | Block identifier. If provided alone, returns all memories for this block across all conversations. If provided with conversationId, returns memories for that specific conversation in this block. |
54-
| `blockName` | string | No | Block name. Alternative to blockId. If provided alone, returns all memories for blocks with this name. If provided with conversationId, returns memories for that conversation in blocks with this name. |
49+
| `conversationId` | string | Yes | Conversation identifier |
5550

5651
#### Output
5752

5853
| Parameter | Type | Description |
5954
| --------- | ---- | ----------- |
60-
| `success` | boolean | Whether the memory was retrieved successfully |
61-
| `memories` | array | Array of memory objects with conversationId, blockId, blockName, and data fields |
62-
| `message` | string | Success or error message |
63-
| `error` | string | Error message if operation failed |
55+
| `success` | boolean | Whether the operation succeeded |
56+
| `memories` | array | Array of messages with `role` and `content` |
57+
| `error` | string | Error message if failed |
6458

6559
### `memory_get_all`
6660

67-
Retrieve all memories from the database
68-
69-
#### Input
70-
71-
| Parameter | Type | Required | Description |
72-
| --------- | ---- | -------- | ----------- |
61+
Retrieve all memories for the current workflow.
7362

7463
#### Output
7564

7665
| Parameter | Type | Description |
7766
| --------- | ---- | ----------- |
78-
| `success` | boolean | Whether all memories were retrieved successfully |
79-
| `memories` | array | Array of all memory objects with key, conversationId, blockId, blockName, and data fields |
80-
| `message` | string | Success or error message |
81-
| `error` | string | Error message if operation failed |
67+
| `success` | boolean | Whether the operation succeeded |
68+
| `memories` | array | All memory objects with `conversationId` and `data` fields |
69+
| `error` | string | Error message if failed |
8270

8371
### `memory_delete`
8472

85-
Delete memories by conversationId, blockId, blockName, or a combination. Supports bulk deletion.
73+
Delete memory by conversation ID.
8674

8775
#### Input
8876

8977
| Parameter | Type | Required | Description |
9078
| --------- | ---- | -------- | ----------- |
91-
| `conversationId` | string | No | Conversation identifier \(e.g., user-123, session-abc\). If provided alone, deletes all memories for this conversation across all blocks. |
92-
| `id` | string | No | Legacy parameter for conversation identifier. Use conversationId instead. Provided for backwards compatibility. |
93-
| `blockId` | string | No | Block identifier. If provided alone, deletes all memories for this block across all conversations. If provided with conversationId, deletes memories for that specific conversation in this block. |
94-
| `blockName` | string | No | Block name. Alternative to blockId. If provided alone, deletes all memories for blocks with this name. If provided with conversationId, deletes memories for that conversation in blocks with this name. |
79+
| `conversationId` | string | Yes | Conversation identifier to delete |
9580

9681
#### Output
9782

9883
| Parameter | Type | Description |
9984
| --------- | ---- | ----------- |
100-
| `success` | boolean | Whether the memory was deleted successfully |
101-
| `message` | string | Success or error message |
102-
| `error` | string | Error message if operation failed |
85+
| `success` | boolean | Whether the operation succeeded |
86+
| `message` | string | Confirmation message |
87+
| `error` | string | Error message if failed |
88+
89+
## Agent Memory Types
10390

91+
When using memory with an Agent block, you can configure how conversation history is managed:
10492

93+
| Type | Description |
94+
| ---- | ----------- |
95+
| **Full Conversation** | Stores all messages, limited by model's context window (uses 90% to leave room for response) |
96+
| **Sliding Window (Messages)** | Keeps the last N messages (default: 10) |
97+
| **Sliding Window (Tokens)** | Keeps messages that fit within a token limit (default: 4000) |
10598

10699
## Notes
107100

108-
- Category: `blocks`
109-
- Type: `memory`
101+
- Memory is scoped per workflow—different workflows have separate memory stores
102+
- The `conversationId` is your responsibility to manage (e.g., use session IDs, user IDs, or UUIDs)
103+
- System messages belong in the Agent block configuration, not in memory

apps/sim/app/api/workflows/[id]/execute/route.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -743,14 +743,17 @@ export async function POST(req: NextRequest, { params }: { params: Promise<{ id:
743743

744744
const onStream = async (streamingExec: StreamingExecution) => {
745745
const blockId = (streamingExec.execution as any).blockId
746+
746747
const reader = streamingExec.stream.getReader()
747748
const decoder = new TextDecoder()
749+
let chunkCount = 0
748750

749751
try {
750752
while (true) {
751753
const { done, value } = await reader.read()
752754
if (done) break
753755

756+
chunkCount++
754757
const chunk = decoder.decode(value, { stream: true })
755758
sendEvent({
756759
type: 'stream:chunk',

apps/sim/app/chat/hooks/use-chat-streaming.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -320,8 +320,8 @@ export function useChatStreaming() {
320320
const trimmedOutput = output.trim()
321321
if (!trimmedOutput) return false
322322

323-
// Skip outputs that exactly match the streamed content to avoid duplication
324-
if (trimmedStreamingContent && trimmedOutput === trimmedStreamingContent) {
323+
// Skip outputs that are already in the streamed content to avoid duplication
324+
if (trimmedStreamingContent?.includes(trimmedOutput)) {
325325
return false
326326
}
327327

apps/sim/executor/constants.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -158,11 +158,19 @@ export const HTTP = {
158158

159159
export const AGENT = {
160160
DEFAULT_MODEL: 'claude-sonnet-4-5',
161-
DEFAULT_FUNCTION_TIMEOUT: 600000, // 10 minutes for custom tool code execution
162-
REQUEST_TIMEOUT: 600000, // 10 minutes for LLM API requests
161+
DEFAULT_FUNCTION_TIMEOUT: 600000,
162+
REQUEST_TIMEOUT: 600000,
163163
CUSTOM_TOOL_PREFIX: 'custom_',
164164
} as const
165165

166+
export const MEMORY = {
167+
DEFAULT_SLIDING_WINDOW_SIZE: 10,
168+
DEFAULT_SLIDING_WINDOW_TOKENS: 4000,
169+
CONTEXT_WINDOW_UTILIZATION: 0.9,
170+
MAX_CONVERSATION_ID_LENGTH: 255,
171+
MAX_MESSAGE_CONTENT_BYTES: 100 * 1024,
172+
} as const
173+
166174
export const ROUTER = {
167175
DEFAULT_MODEL: 'gpt-4o',
168176
DEFAULT_TEMPERATURE: 0,

apps/sim/executor/handlers/agent/agent-handler.test.ts

Lines changed: 28 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1140,7 +1140,7 @@ describe('AgentBlockHandler', () => {
11401140
expect(systemMessages[0].content).toBe('You are a helpful assistant.')
11411141
})
11421142

1143-
it('should prioritize messages array system message over system messages in memories', async () => {
1143+
it('should prefix agent system message before legacy memories', async () => {
11441144
const inputs = {
11451145
model: 'gpt-4o',
11461146
messages: [
@@ -1163,25 +1163,26 @@ describe('AgentBlockHandler', () => {
11631163
const requestBody = JSON.parse(fetchCall[1].body)
11641164

11651165
// Verify messages were built correctly
1166+
// Agent system (1) + legacy memories (3) + user from messages (1) = 5
11661167
expect(requestBody.messages).toBeDefined()
1167-
expect(requestBody.messages.length).toBe(5) // memory system + 2 non-system memories + 2 from messages array
1168+
expect(requestBody.messages.length).toBe(5)
11681169

1169-
// All messages should be present (memories first, then messages array)
1170-
// Memory messages come first
1170+
// Agent's system message is prefixed first
11711171
expect(requestBody.messages[0].role).toBe('system')
1172-
expect(requestBody.messages[0].content).toBe('Old system message from memories.')
1173-
expect(requestBody.messages[1].role).toBe('user')
1174-
expect(requestBody.messages[1].content).toBe('Hello!')
1175-
expect(requestBody.messages[2].role).toBe('assistant')
1176-
expect(requestBody.messages[2].content).toBe('Hi there!')
1177-
// Then messages array
1178-
expect(requestBody.messages[3].role).toBe('system')
1179-
expect(requestBody.messages[3].content).toBe('You are a helpful assistant.')
1172+
expect(requestBody.messages[0].content).toBe('You are a helpful assistant.')
1173+
// Then legacy memories (with their system message preserved)
1174+
expect(requestBody.messages[1].role).toBe('system')
1175+
expect(requestBody.messages[1].content).toBe('Old system message from memories.')
1176+
expect(requestBody.messages[2].role).toBe('user')
1177+
expect(requestBody.messages[2].content).toBe('Hello!')
1178+
expect(requestBody.messages[3].role).toBe('assistant')
1179+
expect(requestBody.messages[3].content).toBe('Hi there!')
1180+
// Then user message from messages array
11801181
expect(requestBody.messages[4].role).toBe('user')
11811182
expect(requestBody.messages[4].content).toBe('What should I do?')
11821183
})
11831184

1184-
it('should handle multiple system messages in memories with messages array', async () => {
1185+
it('should prefix agent system message and preserve legacy memory system messages', async () => {
11851186
const inputs = {
11861187
model: 'gpt-4o',
11871188
messages: [
@@ -1207,21 +1208,23 @@ describe('AgentBlockHandler', () => {
12071208

12081209
// Verify messages were built correctly
12091210
expect(requestBody.messages).toBeDefined()
1210-
expect(requestBody.messages.length).toBe(7) // 5 memory messages (3 system + 2 conversation) + 2 from messages array
1211+
expect(requestBody.messages.length).toBe(7)
12111212

1212-
// All messages should be present in order
1213+
// Agent's system message prefixed first
12131214
expect(requestBody.messages[0].role).toBe('system')
1214-
expect(requestBody.messages[0].content).toBe('First system message.')
1215-
expect(requestBody.messages[1].role).toBe('user')
1216-
expect(requestBody.messages[1].content).toBe('Hello!')
1217-
expect(requestBody.messages[2].role).toBe('system')
1218-
expect(requestBody.messages[2].content).toBe('Second system message.')
1219-
expect(requestBody.messages[3].role).toBe('assistant')
1220-
expect(requestBody.messages[3].content).toBe('Hi there!')
1221-
expect(requestBody.messages[4].role).toBe('system')
1222-
expect(requestBody.messages[4].content).toBe('Third system message.')
1215+
expect(requestBody.messages[0].content).toBe('You are a helpful assistant.')
1216+
// Then legacy memories with their system messages preserved in order
1217+
expect(requestBody.messages[1].role).toBe('system')
1218+
expect(requestBody.messages[1].content).toBe('First system message.')
1219+
expect(requestBody.messages[2].role).toBe('user')
1220+
expect(requestBody.messages[2].content).toBe('Hello!')
1221+
expect(requestBody.messages[3].role).toBe('system')
1222+
expect(requestBody.messages[3].content).toBe('Second system message.')
1223+
expect(requestBody.messages[4].role).toBe('assistant')
1224+
expect(requestBody.messages[4].content).toBe('Hi there!')
12231225
expect(requestBody.messages[5].role).toBe('system')
1224-
expect(requestBody.messages[5].content).toBe('You are a helpful assistant.')
1226+
expect(requestBody.messages[5].content).toBe('Third system message.')
1227+
// Then user message from messages array
12251228
expect(requestBody.messages[6].role).toBe('user')
12261229
expect(requestBody.messages[6].content).toBe('Continue our conversation.')
12271230
})

0 commit comments

Comments
 (0)