fix(eve): address review — async-write status, reasoning filter, turn-bounded capture, best-effort dedup
Review by @kartik-mem0. Root cause across all four: Mem0's hosted add with
infer:true is async and returns a PENDING event before the memory is visible.
- store.ts/tools.ts: add() returns AddResult{status,eventId} via parseAddResult;
the v3 add path returns {status:"PENDING", event_id}, so remember reports
{status:"queued", eventId} for async writes and {status:"saved"} only when
resolved. FAILED/unknown status maps to completed, not queued.
- messages.ts: drop typed non-text parts (reasoning no longer leaks into memory);
bound the captured assistant reply to the current turn and collect all of its
text segments (text->tool->text) instead of a stale prior answer.
- capture.ts + README + eve.mdx: document operationId dedup as best-effort
(lookup+add is not atomic; pending/concurrent windows can double-write);
removed the "restart replays cannot write twice" claim.
Tests: 68 pass (+15). Added reasoning, tool-only/cross-turn, multi-segment,
pending/concurrent capture replay, and PENDING/FAILED add-result cases.
Typecheck + build clean.
This commit is contained in:
@@ -23,7 +23,10 @@ export type FakeSearch = SearchMemoryInput & {
|
||||
query: string;
|
||||
};
|
||||
|
||||
export function createFakeStore(hits: FakeHit[] = []): MemoryStore & {
|
||||
export function createFakeStore(
|
||||
hits: FakeHit[] = [],
|
||||
options: { pendingWrites?: boolean } = {},
|
||||
): MemoryStore & {
|
||||
added: FakeAdd[];
|
||||
searched: FakeSearch[];
|
||||
deleted: string[];
|
||||
@@ -50,11 +53,18 @@ export function createFakeStore(hits: FakeHit[] = []): MemoryStore & {
|
||||
infer: input.infer,
|
||||
metadata: input.metadata,
|
||||
});
|
||||
// Model Mem0's async extraction: a pending write is accepted but its
|
||||
// memory is not yet visible to listByMetadata/get, so it cannot dedupe a
|
||||
// replay. A resolved write becomes immediately visible.
|
||||
if (options.pendingWrites) {
|
||||
return { status: "queued" as const, eventId: `evt_${added.length}` };
|
||||
}
|
||||
records.push({
|
||||
id: `mem_added_${added.length}`,
|
||||
userId: input.userId,
|
||||
metadata: input.metadata,
|
||||
});
|
||||
return { status: "completed" as const };
|
||||
},
|
||||
async search(query, input) {
|
||||
searched.push({ query, ...input });
|
||||
|
||||
Reference in New Issue
Block a user