Catalog PyPI
PACKAGE EXPLORERView in registry

ag2-memorysync

PyPI

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.

ag2agentsautogenconversableagentlong-term-memorymemorymemorysync
Versions collected1
Direct dependencies1From release 1.1.0
Last observed20 Oct, 21:17 UTC

README

Version 1.1.0 documentation

ag2-memorysync

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

Quick start

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.

Why this one

Mem0Zep (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

Semantics worth knowing

  • The reply is never stalled and never broken. Recall blocks at most 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".
  • User turns are sent to fact extraction; only durable facts are stored. Each user turn goes to MemorySync as plain text with 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.
  • Roles follow the speaker, not the hook. A message sent by an agent that speaks for a person — a 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.
  • Attach it to both sides if you like. A process-wide registry records what each attached agent just handled, so the person's words are sent once — not again by the receiving side — and an assistant's reply arriving at the person's proxy is never sent as theirs.
  • Tool/function messages are never sent.
  • 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.

Configuration

ParameterDefaultMeaning
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_k5Memories considered per turn
recall_timeout1.2Hard recall budget, seconds
min_prompt_chars8Skip recall for trivial messages
context_templatebuilt-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

Development

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).

License

MIT

Downloads & popularity

Awaiting observations

No metric observations yet

Download counts and popularity will appear here as the collector receives them.

Versions 1

Collected releases
VersionPublishedDirect dependenciesOpen version
1.1.01 Oct 20261

Package advisories

0
No matching advisories collected

This describes our collected data; it is not a security assessment.

Repository

PENDING
memorysyncio/memorysync-plugins

Shared repository data · GitHub

License detected in repository
Not collected

Metadata history

Meaningful changes
Current collected state Current

Observed since 20 Oct, 21:17 UTC

No superseded metadata states collected. Unchanged observations do not create new revisions.

Record identity

package:d610593fb7dba857f992d364929843d69c8d00dc7d3866f4d1b105caf4e0660f