Observed since 20 Oct, 21:17 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
MemorySync for AG2 (AutoGen classic): an automatic memory loop on ConversableAgent's hook system — budgeted recall injection, duplicate-proof capture of the user's turns for fact extraction, and a deadlock-free sync bridge.
MemorySync for AG2
(the classic AutoGen ConversableAgent framework, pip install autogen):
an automatic memory loop — recall injected before every reply, the user's
turns captured for fact extraction, zero extra code per turn.
pip install ag2-memorysync
from autogen import ConversableAgent
from ag2_memorysync import MemorySyncCapability
assistant = ConversableAgent("assistant", llm_config=...)
memory = MemorySyncCapability(
api_key="ms_...", # or MEMORYSYNC_API_KEY
user_id="customer-42", # required — who these memories belong to
session_id="support-chat", # tags the facts from this chat
)
memory.add_to_agent(assistant) # that's the whole integration
From then on every incoming user message is enriched with recalled
context and sent to MemorySync, which extracts the durable facts it
contains — through AG2's own hook system (process_last_received_message
process_message_before_send). The agent's own replies are not sent:
assistant replies are not stored as memories.| Mem0 | Zep (zep-ag2) | MemorySync | |
|---|---|---|---|
| AG2 adapter exists | ✗ docs show an AutoGen-0.2 recipe with placeholder model names | ✓ | ✓ |
| Multi-agent duplication | — | ✗ documented bug: two attached agents store every utterance twice with conflicting roles | ✓ cross-hook dedup registry + idempotency seeds — each utterance handled once; an agent's reply is never sent as the person's words (by test) |
| Sync→async bridge | — | per-call event-loop spin; documented deadlock caveat under asyncio | ✓ one persistent background loop; never touches the caller's loop (asyncio-driven chats pass, by test) |
| Recall latency budget | — | ✗ none | ✓ hard 1.2s default — the reply is never late |
| Framework pin | — | ✗ ag2<1 — breaks on the v1 rewrite | ✓ zero framework dependency (duck-typed attach; works with whichever classic distribution you installed) |
| Injected context re-captured? | — | system-message mutation, last-write-wins | ✓ hook output feeds the LLM only; the ORIGINAL text is what is sent |
recall_timeout (default 1.2s); sending a turn is fire-and-forget off
the hot path. Outages and quota exhaustion degrade to "no memories
this turn".role: "user" under the ag2::<session> session scope. The server
extracts the durable facts it contains and stores only those, tagged
with session_id: "ag2::<session>"; filler such as "ok" or "thanks"
yields none, and the turn text itself is not stored. Deterministic
idempotency seeds let the server recognise a retry of the same turn and
not extract it twice.UserProxyAgent, an agent whose
human_input_mode is "ALWAYS", or a "TERMINATE"-mode agent with no
model — is the user's turn, even when the capability is attached to
that agent too. Every other agent's outgoing message is an assistant
reply and is not sent. That includes a plain
ConversableAgent(..., llm_config=...): its default
human_input_mode="TERMINATE" only asks a person when the chat ends,
so its messages come from the model.register_memory_tools(memory, caller=..., executor=...) adds
search_memory + save_memory tools (the caller needs an
llm_config, as usual for AG2 tools).memory.flush() waits for in-flight sends (shutdown/tests);
memory.close() flushes and releases the HTTP client.| Parameter | Default | Meaning |
|---|---|---|
user_id | — (required) | End user the memories belong to |
session_id | "default" | Session scope: the session_id (ag2::<session>) carried by the facts from this chat |
top_k | 5 | Memories considered per turn |
recall_timeout | 1.2 | Hard recall budget, seconds |
min_prompt_chars | 8 | Skip recall for trivial messages |
context_template | built-in | {context} placeholder, brace-safe .replace rendering |
capture | "both" | "received" / "sent" to capture one side only. The sent side carries only what an agent speaking for a person says, so "sent" belongs on the person's UserProxyAgent; on an assistant it sends nothing |
pip install -e . "autogen[openai]" pytest "httpx>=0.25,<1"
python -m pytest tests -q # 31 tests through REAL ConversableAgent chats
The suite includes a reproduction of zep-ag2's documented multi-agent
double-store scenario (each utterance handled once), a UserProxyAgent +
assistant chat with the capability on both sides (the person's words are
sent once; the assistant's replies are not sent), and a chat driven from
inside asyncio.run() (no deadlock).
MIT
Download counts and popularity will appear here as the collector receives them.
| Version | Published | Direct dependencies | Open version |
|---|---|---|---|
| 1.1.0 | 1 Oct 2026 | 1 |
This describes our collected data; it is not a security assessment.
Shared repository data · GitHub
Observed since 20 Oct, 21:17 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
package:d610593fb7dba857f992d364929843d69c8d00dc7d3866f4d1b105caf4e0660f