Skip to content

Commit e0c04c2

Browse files
committed
address comments
1 parent 080ae8b commit e0c04c2

11 files changed

Lines changed: 140 additions & 78 deletions

File tree

apps/sim/app/api/memory/[id]/route.ts

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,13 @@ export const DELETE = withRouteHandler(
131131
const existingMemory = await db
132132
.select({ id: memory.id })
133133
.from(memory)
134-
.where(and(eq(memory.key, id), eq(memory.workspaceId, validatedWorkspaceId)))
134+
.where(
135+
and(
136+
eq(memory.key, id),
137+
eq(memory.workspaceId, validatedWorkspaceId),
138+
isNull(memory.deletedAt)
139+
)
140+
)
135141
.limit(1)
136142

137143
if (existingMemory.length === 0) {
@@ -140,7 +146,13 @@ export const DELETE = withRouteHandler(
140146

141147
await db
142148
.delete(memory)
143-
.where(and(eq(memory.key, id), eq(memory.workspaceId, validatedWorkspaceId)))
149+
.where(
150+
and(
151+
eq(memory.key, id),
152+
eq(memory.workspaceId, validatedWorkspaceId),
153+
isNull(memory.deletedAt)
154+
)
155+
)
144156

145157
logger.info(`[${requestId}] Memory deleted: ${id} for workspace: ${validatedWorkspaceId}`)
146158
return NextResponse.json(
@@ -183,7 +195,13 @@ export const PUT = withRouteHandler(async (request: NextRequest, context: Memory
183195
const existingMemories = await db
184196
.select()
185197
.from(memory)
186-
.where(and(eq(memory.key, id), eq(memory.workspaceId, validatedWorkspaceId)))
198+
.where(
199+
and(
200+
eq(memory.key, id),
201+
eq(memory.workspaceId, validatedWorkspaceId),
202+
isNull(memory.deletedAt)
203+
)
204+
)
187205
.limit(1)
188206

189207
if (existingMemories.length === 0) {
@@ -202,12 +220,24 @@ export const PUT = withRouteHandler(async (request: NextRequest, context: Memory
202220
await db
203221
.update(memory)
204222
.set({ data: validatedData, updatedAt: now })
205-
.where(and(eq(memory.key, id), eq(memory.workspaceId, validatedWorkspaceId)))
223+
.where(
224+
and(
225+
eq(memory.key, id),
226+
eq(memory.workspaceId, validatedWorkspaceId),
227+
isNull(memory.deletedAt)
228+
)
229+
)
206230

207231
const updatedMemories = await db
208232
.select()
209233
.from(memory)
210-
.where(and(eq(memory.key, id), eq(memory.workspaceId, validatedWorkspaceId)))
234+
.where(
235+
and(
236+
eq(memory.key, id),
237+
eq(memory.workspaceId, validatedWorkspaceId),
238+
isNull(memory.deletedAt)
239+
)
240+
)
211241
.limit(1)
212242

213243
const mem = updatedMemories[0]

apps/sim/app/api/memory/route.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,13 @@ export const DELETE = withRouteHandler(async (request: NextRequest) => {
293293

294294
const result = await db
295295
.delete(memory)
296-
.where(and(eq(memory.key, conversationId), eq(memory.workspaceId, workspaceId)))
296+
.where(
297+
and(
298+
eq(memory.key, conversationId),
299+
eq(memory.workspaceId, workspaceId),
300+
isNull(memory.deletedAt)
301+
)
302+
)
297303
.returning({ id: memory.id })
298304

299305
const deletedCount = result.length

apps/sim/blocks/blocks/mem0.test.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,21 @@ describe('Mem0Block', () => {
3232
})
3333
).toThrow('Each message must have role user or assistant and non-empty content')
3434
})
35+
36+
it('passes pagination params for get operations', () => {
37+
const params = buildParams({
38+
operation: 'get',
39+
apiKey: 'test-key',
40+
userId: 'alice',
41+
page: '2',
42+
limit: '25',
43+
})
44+
45+
expect(params).toEqual({
46+
apiKey: 'test-key',
47+
userId: 'alice',
48+
page: 2,
49+
limit: 25,
50+
})
51+
})
3552
})

apps/sim/blocks/blocks/mem0.ts

Lines changed: 19 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,8 @@
11
import { toError } from '@sim/utils/errors'
22
import { Mem0Icon } from '@/components/icons'
33
import { AuthMode, type BlockConfig, IntegrationType } from '@/blocks/types'
4-
import type { Mem0Message, Mem0Response } from '@/tools/mem0/types'
5-
6-
function isMem0Message(value: unknown): value is Mem0Message {
7-
return (
8-
Boolean(value) &&
9-
typeof value === 'object' &&
10-
'role' in value &&
11-
'content' in value &&
12-
(value.role === 'user' || value.role === 'assistant') &&
13-
typeof value.content === 'string' &&
14-
value.content.length > 0
15-
)
16-
}
17-
18-
function parseMem0Messages(value: unknown): Mem0Message[] {
19-
if (!value) {
20-
throw new Error('Messages are required for add operation')
21-
}
22-
23-
let messages: unknown
24-
try {
25-
messages = typeof value === 'string' ? JSON.parse(value) : value
26-
} catch (error) {
27-
throw new Error(`Messages must be valid JSON: ${toError(error).message}`)
28-
}
29-
30-
if (!Array.isArray(messages) || messages.length === 0) {
31-
throw new Error('Messages must be a non-empty array')
32-
}
33-
34-
const validMessages: Mem0Message[] = []
35-
for (const message of messages) {
36-
if (!isMem0Message(message)) {
37-
throw new Error('Each message must have role user or assistant and non-empty content')
38-
}
39-
validMessages.push(message)
40-
}
41-
42-
return validMessages
43-
}
4+
import type { Mem0Response } from '@/tools/mem0/types'
5+
import { parseMem0Messages } from '@/tools/mem0/utils'
446

457
export const Mem0Block: BlockConfig<Mem0Response> = {
468
type: 'mem0',
@@ -163,6 +125,17 @@ Return ONLY the date string in YYYY-MM-DD format - no explanations, no quotes, n
163125
password: true,
164126
required: true,
165127
},
128+
{
129+
id: 'page',
130+
title: 'Page',
131+
type: 'short-input',
132+
placeholder: '1',
133+
condition: {
134+
field: 'operation',
135+
value: 'get',
136+
},
137+
mode: 'advanced',
138+
},
166139
{
167140
id: 'limit',
168141
title: 'Result Limit',
@@ -228,7 +201,7 @@ Return ONLY the date string in YYYY-MM-DD format - no explanations, no quotes, n
228201

229202
if (params.userId) result.userId = params.userId
230203

231-
if (params.limit) result.limit = params.limit
204+
if (params.limit) result.limit = Number(params.limit)
232205

233206
switch (operation) {
234207
case 'add':
@@ -260,6 +233,10 @@ Return ONLY the date string in YYYY-MM-DD format - no explanations, no quotes, n
260233
result.memoryId = params.memoryId
261234
}
262235

236+
if (params.page) {
237+
result.page = Number(params.page)
238+
}
239+
263240
if (params.startDate) {
264241
result.startDate = params.startDate
265242
}
@@ -283,6 +260,7 @@ Return ONLY the date string in YYYY-MM-DD format - no explanations, no quotes, n
283260
memoryId: { type: 'string', description: 'Memory identifier' },
284261
startDate: { type: 'string', description: 'Start date filter' },
285262
endDate: { type: 'string', description: 'End date filter' },
263+
page: { type: 'number', description: 'Page number for paginated get results' },
286264
limit: { type: 'number', description: 'Result limit' },
287265
},
288266
outputs: {

apps/sim/tools/mem0/add_memories.test.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,16 @@ describe('mem0AddMemoriesTool', () => {
4040
})
4141
})
4242

43+
it('rejects unsupported message roles before building the request body', () => {
44+
expect(() =>
45+
buildBody({
46+
apiKey: 'test-key',
47+
userId: 'alice',
48+
messages: JSON.stringify([{ role: 'system', content: 'Remember this.' }]),
49+
})
50+
).toThrow('Each message must have role user or assistant and non-empty content')
51+
})
52+
4353
it('extracts queued processing fields from v3 responses', async () => {
4454
const result = await transformResponse(
4555
new Response(

apps/sim/tools/mem0/add_memories.ts

Lines changed: 2 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,11 @@
1-
import { toError } from '@sim/utils/errors'
21
import {
32
ADD_MEMORY_OUTPUT_PROPERTIES,
43
type Mem0AddMemoriesParams,
54
type Mem0AddMemoriesResponse,
6-
type Mem0Message,
75
} from '@/tools/mem0/types'
6+
import { parseMem0Messages } from '@/tools/mem0/utils'
87
import type { ToolConfig } from '@/tools/types'
98

10-
function parseMessages(messages: Mem0AddMemoriesParams['messages']): Mem0Message[] {
11-
let parsed: unknown
12-
try {
13-
parsed = typeof messages === 'string' ? JSON.parse(messages) : messages
14-
} catch (error) {
15-
throw new Error(`Messages must be valid JSON: ${toError(error).message}`)
16-
}
17-
if (!Array.isArray(parsed) || parsed.length === 0) {
18-
throw new Error('Messages must be a non-empty array')
19-
}
20-
21-
for (const message of parsed) {
22-
if (
23-
!message ||
24-
typeof message !== 'object' ||
25-
(message.role !== 'user' && message.role !== 'assistant') ||
26-
typeof message.content !== 'string' ||
27-
message.content.length === 0
28-
) {
29-
throw new Error('Each message must have role user or assistant and non-empty content')
30-
}
31-
}
32-
33-
return parsed
34-
}
35-
369
/**
3710
* Add Memories Tool
3811
* @see https://docs.mem0.ai/api-reference/memory/add-memories
@@ -73,7 +46,7 @@ export const mem0AddMemoriesTool: ToolConfig<Mem0AddMemoriesParams, Mem0AddMemor
7346
'Content-Type': 'application/json',
7447
}),
7548
body: (params) => {
76-
const messages = parseMessages(params.messages)
49+
const messages = parseMem0Messages(params.messages)
7750
return {
7851
messages,
7952
user_id: params.userId.trim(),

apps/sim/tools/mem0/get_memories.test.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ interface Mem0GetParams {
1010
memoryId?: string
1111
startDate?: string
1212
endDate?: string
13+
page?: number
1314
limit?: number
1415
}
1516

@@ -23,6 +24,7 @@ describe('mem0GetMemoriesTool', () => {
2324
const params = {
2425
apiKey: 'test-key',
2526
userId: 'user-123',
27+
page: 3,
2628
limit: 25,
2729
}
2830

@@ -32,7 +34,7 @@ describe('mem0GetMemoriesTool', () => {
3234
filters: {
3335
user_id: 'user-123',
3436
},
35-
page: 1,
37+
page: 3,
3638
page_size: 25,
3739
})
3840
})

apps/sim/tools/mem0/get_memories.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,13 @@ export const mem0GetMemoriesTool: ToolConfig<Mem0GetMemoriesParams> = {
6060
visibility: 'user-or-llm',
6161
description: 'Maximum number of results to return (e.g., 10, 50, 100)',
6262
},
63+
page: {
64+
type: 'number',
65+
required: false,
66+
default: 1,
67+
visibility: 'user-or-llm',
68+
description: 'Page number to retrieve for paginated list results',
69+
},
6370
apiKey: {
6471
type: 'string',
6572
required: true,
@@ -103,7 +110,7 @@ export const mem0GetMemoriesTool: ToolConfig<Mem0GetMemoriesParams> = {
103110

104111
return {
105112
filters,
106-
page: 1,
113+
page: Number(params.page ?? 1),
107114
page_size: Number(params.limit || 10),
108115
}
109116
},

apps/sim/tools/mem0/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ import { mem0SearchMemoriesTool } from '@/tools/mem0/search_memories'
44

55
export { mem0AddMemoriesTool, mem0SearchMemoriesTool, mem0GetMemoriesTool }
66
export * from '@/tools/mem0/types'
7+
export * from '@/tools/mem0/utils'

apps/sim/tools/mem0/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ export interface Mem0GetMemoriesParams {
2323
memoryId?: string
2424
startDate?: string
2525
endDate?: string
26+
page?: number
2627
limit?: number
2728
apiKey: string
2829
}

0 commit comments

Comments
 (0)