Skip to content

Commit 0299d9f

Browse files
committed
Fix discrete_memory_extracted flag in MCP memory search
- Add ExtractedMemoryRecord class for explicit memories (defaults to 't') - Keep MemoryRecord for raw messages (defaults to 'f') - Update CreateMemoryRecordRequest to use ExtractedMemoryRecord - Update LenientMemoryRecord to inherit from ExtractedMemoryRecord - Fix Redis vector store adapter to preserve discrete_memory_extracted field during search - Update long_term_memory.py type signatures to accept both memory classes This resolves the issue where MCP-created memories were incorrectly showing discrete_memory_extracted='f' instead of 't' in search results.
1 parent 9265184 commit 0299d9f

File tree

5 files changed

+35
-9
lines changed

5 files changed

+35
-9
lines changed

agent-memory-client/agent_memory_client/models.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ class MemoryRecord(BaseModel):
110110
)
111111
discrete_memory_extracted: Literal["t", "f"] = Field(
112112
default="f",
113-
description="Whether memory extraction has run for this memory (only messages)",
113+
description="Whether memory extraction has run for this memory",
114114
)
115115
memory_type: MemoryTypeEnum = Field(
116116
default=MemoryTypeEnum.MESSAGE,
@@ -130,6 +130,19 @@ class MemoryRecord(BaseModel):
130130
)
131131

132132

133+
class ExtractedMemoryRecord(MemoryRecord):
134+
"""A memory record that has already been extracted (e.g., explicit memories from API/MCP)"""
135+
136+
discrete_memory_extracted: Literal["t", "f"] = Field(
137+
default="t",
138+
description="Whether memory extraction has run for this memory",
139+
)
140+
memory_type: MemoryTypeEnum = Field(
141+
default=MemoryTypeEnum.SEMANTIC,
142+
description="Type of memory",
143+
)
144+
145+
133146
class ClientMemoryRecord(MemoryRecord):
134147
"""A memory record with a client-provided ID"""
135148

agent_memory_server/cli.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,11 +128,14 @@ async def setup_and_run():
128128
logger.info(f"Starting MCP server on port {port}\n")
129129
await mcp_app.run_sse_async()
130130
elif mode == "stdio":
131-
# Logging already configured above
131+
# Don't run a task worker in stdio mode.
132+
# TODO: Make configurable with a CLI flag?
133+
settings.use_docket = False
132134
await mcp_app.run_stdio_async()
133135
else:
134136
raise ValueError(f"Invalid mode: {mode}")
135137

138+
# TODO: Do we really need to update the port again?
136139
# Update the port in settings
137140
settings.mcp_port = port
138141

agent_memory_server/long_term_memory.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1204,7 +1204,6 @@ async def promote_working_memory_to_long_term(
12041204
text=f"{msg.role}: {msg.content}",
12051205
namespace=namespace,
12061206
user_id=current_working_memory.user_id,
1207-
memory_type=MemoryTypeEnum.MESSAGE,
12081207
persisted_at=None,
12091208
)
12101209

agent_memory_server/mcp.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -310,9 +310,7 @@ async def create_long_term_memories(
310310
if mem.user_id is None and settings.default_mcp_user_id:
311311
mem.user_id = settings.default_mcp_user_id
312312

313-
payload = CreateMemoryRecordRequest(
314-
memories=[MemoryRecord(**mem.model_dump()) for mem in memories]
315-
)
313+
payload = CreateMemoryRecordRequest(memories=memories)
316314
return await core_create_long_term_memory(
317315
payload, background_tasks=get_background_tasks()
318316
)

agent_memory_server/models.py

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ class MemoryRecord(BaseModel):
130130
)
131131
discrete_memory_extracted: Literal["t", "f"] = Field(
132132
default="f",
133-
description="Whether memory extraction has run for this memory (only messages)",
133+
description="Whether memory extraction has run for this memory",
134134
)
135135
memory_type: MemoryTypeEnum = Field(
136136
default=MemoryTypeEnum.MESSAGE,
@@ -150,6 +150,19 @@ class MemoryRecord(BaseModel):
150150
)
151151

152152

153+
class ExtractedMemoryRecord(MemoryRecord):
154+
"""A memory record that has already been extracted (e.g., explicit memories from API/MCP)"""
155+
156+
discrete_memory_extracted: Literal["t", "f"] = Field(
157+
default="t",
158+
description="Whether memory extraction has run for this memory",
159+
)
160+
memory_type: MemoryTypeEnum = Field(
161+
default=MemoryTypeEnum.SEMANTIC,
162+
description="Type of memory",
163+
)
164+
165+
153166
class ClientMemoryRecord(MemoryRecord):
154167
"""A memory record with a client-provided ID"""
155168

@@ -268,7 +281,7 @@ class MemoryRecordResultsResponse(MemoryRecordResults):
268281
class CreateMemoryRecordRequest(BaseModel):
269282
"""Payload for creating memory records"""
270283

271-
memories: list[MemoryRecord]
284+
memories: list[ExtractedMemoryRecord]
272285

273286

274287
class GetSessionsQuery(BaseModel):
@@ -401,7 +414,7 @@ class MemoryPromptResponse(BaseModel):
401414
messages: list[base.Message | SystemMessage]
402415

403416

404-
class LenientMemoryRecord(MemoryRecord):
417+
class LenientMemoryRecord(ExtractedMemoryRecord):
405418
"""A memory record that can be created without an ID"""
406419

407420
id: str | None = Field(default_factory=lambda: str(ULID()))

0 commit comments

Comments
 (0)