Skip to content

feat(memory): added memory block and tool#372

Merged
emir-karabeg merged 6 commits intomainfrom
feat/memory
May 19, 2025
Merged

feat(memory): added memory block and tool#372
emir-karabeg merged 6 commits intomainfrom
feat/memory

Conversation

@emir-karabeg
Copy link
Copy Markdown
Collaborator

@emir-karabeg emir-karabeg commented May 18, 2025

Description

Created memory block and tool/service. Added agent raw message history and advanced mode.

Type of change

  • New feature (non-breaking change which adds functionality)

How Has This Been Tested?

Create a memory store and modify it or delete it using the memory block.

Checklist:

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have added tests that prove my fix is effective or that my feature works
  • All tests pass locally and in CI (bun run test)
  • My changes generate no new warnings
  • Any dependent changes have been merged and published in downstream modules
  • I have updated version numbers as needed (if needed)
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

Security Considerations:

  • My changes do not introduce any new security vulnerabilities
  • I have considered the security implications of my changes

@vercel
Copy link
Copy Markdown

vercel Bot commented May 18, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
sim ✅ Ready (Inspect) Visit Preview 💬 Add feedback May 19, 2025 9:58am
1 Skipped Deployment
Name Status Preview Comments Updated (UTC)
docs ⬜️ Skipped (Inspect) May 19, 2025 9:58am

Copy link
Copy Markdown
Contributor

@greptile-apps greptile-apps Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR Summary

This PR introduces a comprehensive memory system for workflows, enabling persistent storage and retrieval of both agent and raw data types. The implementation includes API routes, database schema, and memory block tools for managing workflow-specific memories.

  • Added new memory table with proper indexing and soft delete capability in /apps/sim/db/migrations/0038_shocking_thor.sql
  • Implemented RESTful memory API endpoints with workflowId validation and type-specific data handling in /apps/sim/app/api/memory/route.ts and /apps/sim/app/api/memory/[id]/route.ts
  • Created memory block tools (add, get, getAll, delete) with proper validation and error handling in /apps/sim/tools/memory/
  • Added memory block UI configuration with conditional rendering based on operation type in /apps/sim/blocks/blocks/memory.ts
  • Integrated memory tools into the main registry with proper type definitions and interfaces in /apps/sim/tools/registry.ts

💡 (5/5) You can turn off certain types of comments like style here!

17 file(s) reviewed, 26 comment(s)
Edit PR Review Bot Settings | Greptile

const workflowId = url.searchParams.get('workflowId')
const searchQuery = url.searchParams.get('query')
const type = url.searchParams.get('type')
const limit = parseInt(url.searchParams.get('limit') || '50')
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic: Add validation for negative limit values and set a reasonable maximum limit to prevent excessive data retrieval

Suggested change
const limit = parseInt(url.searchParams.get('limit') || '50')
const rawLimit = parseInt(url.searchParams.get('limit') || '50')
const limit = Math.min(Math.max(1, rawLimit), 100) // Ensure limit is between 1 and 100

Comment on lines +147 to +159
// Soft delete by setting deletedAt timestamp
await db
.update(memory)
.set({
deletedAt: new Date(),
updatedAt: new Date()
})
.where(
and(
eq(memory.key, id),
eq(memory.workflowId, workflowId)
)
)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic: Missing isNull(memory.deletedAt) in WHERE clause could allow updating already soft-deleted records

Suggested change
// Soft delete by setting deletedAt timestamp
await db
.update(memory)
.set({
deletedAt: new Date(),
updatedAt: new Date()
})
.where(
and(
eq(memory.key, id),
eq(memory.workflowId, workflowId)
)
)
// Soft delete by setting deletedAt timestamp
await db
.update(memory)
.set({
deletedAt: new Date(),
updatedAt: new Date()
})
.where(
and(
eq(memory.key, id),
eq(memory.workflowId, workflowId),
isNull(memory.deletedAt)
)
)

Comment on lines +298 to +307
const updatedMemories = await db
.select()
.from(memory)
.where(
and(
eq(memory.key, id),
eq(memory.workflowId, workflowId)
)
)
.limit(1)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic: Missing isNull(memory.deletedAt) check when fetching updated memory could return soft-deleted records

Suggested change
const updatedMemories = await db
.select()
.from(memory)
.where(
and(
eq(memory.key, id),
eq(memory.workflowId, workflowId)
)
)
.limit(1)
const updatedMemories = await db
.select()
.from(memory)
.where(
and(
eq(memory.key, id),
eq(memory.workflowId, workflowId),
isNull(memory.deletedAt)
)
)
.limit(1)

Comment on lines +252 to +264
// Update the existing memory with appended data
await db
.update(memory)
.set({
data: updatedData,
updatedAt: new Date()
})
.where(
and(
eq(memory.key, key),
eq(memory.workflowId, workflowId)
)
)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic: Missing deletedAt check in update query could allow updates to soft-deleted records

Suggested change
// Update the existing memory with appended data
await db
.update(memory)
.set({
data: updatedData,
updatedAt: new Date()
})
.where(
and(
eq(memory.key, key),
eq(memory.workflowId, workflowId)
)
)
// Update the existing memory with appended data
await db
.update(memory)
.set({
data: updatedData,
updatedAt: new Date()
})
.where(
and(
eq(memory.key, key),
eq(memory.workflowId, workflowId),
isNull(memory.deletedAt)
)
)

Comment on lines +111 to +113
operation: { type: 'string', required: true },
id: { type: 'string', required: true },
type: { type: 'string', required: false },
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic: id is marked as required in inputs but type is optional, which conflicts with validation logic that requires type for 'add' operation

Suggested change
operation: { type: 'string', required: true },
id: { type: 'string', required: true },
type: { type: 'string', required: false },
operation: { type: 'string', required: true },
id: { type: 'string', required: true },
type: { type: 'string', required: true },

import { memoryGetAllTool } from './get_all_memories'
import { memoryDeleteTool } from './delete_memory'

export { memoryAddTool, memoryGetTool, memoryGetAllTool, memoryDeleteTool } No newline at end of file
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: Missing newline at end of file

Suggested change
export { memoryAddTool, memoryGetTool, memoryGetAllTool, memoryDeleteTool }
export { memoryAddTool, memoryGetTool, memoryGetAllTool, memoryDeleteTool }

import { MemoryResponse } from './types'

// Get Memory Tool
export const memoryGetTool: ToolConfig<any, MemoryResponse> = {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: Using any in ToolConfig generic type parameter reduces type safety. Consider creating proper type for the params object.

Suggested change
export const memoryGetTool: ToolConfig<any, MemoryResponse> = {
export const memoryGetTool: ToolConfig<{ id: string }, MemoryResponse> = {

}
},
request: {
url: (params): any => {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: Return type any on url function could be more specific like string | ErrorResponse

Comment on lines +5 to +6
memory?: any
memories?: any[]
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: Using any type reduces type safety. Consider defining specific types for memory and memories based on MemoryRecord

}

export interface RawMemoryData {
[key: string]: any
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: Using index signature with any value type reduces type safety. Consider creating a more specific type or using generics

@emir-karabeg emir-karabeg changed the title feat(memory): added memory block and service feat(memory): added memory block and tool May 18, 2025
@vercel vercel Bot temporarily deployed to Preview – docs May 19, 2025 09:54 Inactive
@emir-karabeg emir-karabeg merged commit 39a1e6f into main May 19, 2025
3 of 4 checks passed
@emir-karabeg emir-karabeg deleted the feat/memory branch May 19, 2025 09:54
emir-karabeg added a commit that referenced this pull request May 19, 2025
* feat(memory): added memory block and service

* feat(memory): ran migrations

* improvement(memory): appending memories; console messages

* feat(memory): added agent raw message history input UI

* feat(agent-messages): added agent message history

* improvement: added tests
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant