Skip to content

Conversation

@abrookins
Copy link
Collaborator

The memory server indexes any messages from working memory into "message" type memory records in long-term memory. However, we were not attempting to deduplicate these memory records -- only the higher-level long-term memory types, like semantic and episodic memory.

This change refactors the logic we use to store messages long-term such that they work similarly to long-term memories the client adds to working memory. When a client adds a message to working memory, the client gives the memory an ID, and the memory gets a blank persisted_at timestamp. After setting working memory, we kick off a background task to persist any promoted long-term memories and messages in long-term memory. When we copy the messages into long-term memory, we now update the persisted_at timestamp. If we see that working memory again and try to persist any new memories or messages, we'll skip any that have already been persisted.

The memory server indexes any messages from working memory into
"message" type memory records in long-term memory. However, we
were not attempting to deduplicate these memory records -- only
the higher-level long-term memory types, like semantic and episodic
memory.

This change refactors the logic we use to store messages long-term
such that they work similarly to long-term memories the client adds
to working memory. When a client adds a message to working memory,
the client gives the memory an ID, and the memory gets a blank
`persisted_at` timestamp. After setting working memory, we kick
off a background task to persist any promoted long-term memories
and messages in long-term memory. When we copy the messages into
long-term memory, we now update the `persisted_at` timestamp. If
we see that working memory again and try to persist any new memories
or messages, we'll skip any that have already been persisted.
Copilot AI review requested due to automatic review settings July 9, 2025 19:26
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR refactors message handling so that long-term “message” memories support deduplication and proper persisted timestamps, aligning their lifecycle with other memory types.

  • Added id and persisted_at fields to MemoryMessage in both server and client models
  • Updated set_working_memory and promote_working_memory_to_long_term to initialize, dedupe, and batch‐persist messages
  • Adjusted client methods and tests to use MemoryMessage objects with attribute access

Reviewed Changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
tests/test_client_enhancements.py Switched test assertions from dict indexing (["content"]) to attribute access (.content).
tests/test_client_api.py Same as above for MemoryAPIClient; updated indexing assertions.
tests/test_api.py Broadened response checks: validate message count, roles, contents, and auto-generated IDs.
agent_memory_server/models.py Added id and persisted_at fields to MemoryMessage.
agent_memory_server/mcp.py In set_working_memory, convert all messages to MemoryMessage with persisted_at=None.
agent_memory_server/long_term_memory.py In promote_working_memory_to_long_term, identify unpersisted messages, dedupe by ID, set persisted_at, and index them.
agent_memory_server/api.py Removed old message‐indexing logic; now only schedules promotion for structured memories.
agent-memory-client/models.py Converted client MemoryMessage from TypedDict to BaseModel, added tracking fields.
agent-memory-client/client.py Updated append_messages_to_working_memory to accept and convert MemoryMessage objects.
Comments suppressed due to low confidence (1)

agent_memory_server/mcp.py:694

  • [nitpick] The docstring describes only dict inputs. It should also note that MemoryMessage objects are accepted directly.
        messages: List of conversation messages (role/content pairs with optional id/persisted_at)

Copy link

@rbs333 rbs333 left a comment

Choose a reason for hiding this comment

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

LGTM

@abrookins abrookins merged commit f66c07d into main Jul 11, 2025
9 checks passed
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.

3 participants