Metadata-Version: 2.5
Name: agent-framework-memorysync
Version: 1.0.0
Summary: MemorySync for Microsoft Agent Framework: a ContextProvider with budgeted instruction-layer recall, per-run identity, once-per-turn duplicate-proof capture, and fail-open everything.
Project-URL: Homepage, https://docs.memorysync.io/guides/agent-framework
Project-URL: Documentation, https://docs.memorysync.io/guides/agent-framework
Project-URL: Repository, https://github.com/memorysyncio/memorysync-plugins
Author-email: MemorySync <support@memorysync.io>
License-Expression: MIT
Keywords: agent-framework,agents,context-provider,long-term-memory,memory,memorysync,microsoft
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Requires-Python: >=3.10
Requires-Dist: agent-framework-core<2,>=1.8
Requires-Dist: httpx<1,>=0.25
Description-Content-Type: text/markdown

# agent-framework-memorysync

[MemorySync](https://memorysync.io) for the
[Microsoft Agent Framework](https://github.com/microsoft/agent-framework):
agents that remember users across sessions — without ever stalling a run.

```bash
pip install agent-framework-memorysync
```

## Quick start

```python
from agent_framework import Agent
from agent_framework_memorysync import MemorySyncContextProvider

provider = MemorySyncContextProvider(
    api_key="ms_...",          # or MEMORYSYNC_API_KEY
    user_id="customer-42",     # required — who these memories belong to
    session_id="support",      # scopes the transcript
)

agent = Agent(client=..., context_providers=[provider])
result = await agent.run("which seat should I book?")
```

Every run recalls relevant memories into the **instructions layer** under
a hard budget, and both sides of the exchange persist automatically after
the run — no extra code per turn.

## Why this one

| | Mem0 (`agent-framework-mem0`, in-repo) | Zep (`zep-ms-agent-framework`) | **MemorySync** |
| --- | --- | --- | --- |
| Injection layer | ✗ fabricates a `role="user"` message | ✓ instructions | ✓ instructions |
| Recall latency budget | ✗ none | ✗ none | ✓ hard 1.2s default — a slow backend means an unenriched run, never a late one |
| Capture failure behaviour | ✗ **`after_run` errors crash the agent** | swallowed | ✓ entirely fail-open, logged |
| Scope model | ✗ storage ≠ retrieval scopes — forget `search_user_id` and the agent is silently memoryless | single | ✓ one `user_id` drives both — the bug cannot exist |
| Per-run identity | ✗ construction-only | ✗ construction-only (documented) | ✓ `agent.run(..., options={"memorysync_user_id": ...})` or a `user_id_resolver` |
| Write dedup | ✗ re-adds every turn | ✗ | ✓ deterministic idempotency seeds |
| Tool-loop double-capture | ✗ | — | ✓ `after_run_once_per_turn = True` |
| Release status | beta (`1.0.0b…`) | 0.2.1 | ✓ stable 1.0.0 |
| Python | ≥3.10 | ✗ ≥3.11 only | ✓ ≥3.10 (matches the framework) |

## Semantics worth knowing

- Turns store verbatim under the `agent-framework::<session>` transcript
  scope — separate history, same shared user memories as every other
  MemorySync surface.
- The resolved run identity is pinned in the provider's session-state
  slice, so recall and capture can never diverge within a run — and the
  slice stays JSON-native, so `AgentSession` serialization keeps working.
- `expose_search_tool=True` adds `search_memory` + `save_memory` tools
  via `context.extend_tools`.
- Free-tier quota exhaustion is silent by design (adds accepted-without-
  storing, reads empty); evaluation keys surface strict `429`s.

## Configuration

| Parameter | Default | Meaning |
| --- | --- | --- |
| `user_id` | — (required) | End user the memories belong to |
| `session_id` | `"default"` | Transcript scope |
| `top_k` | `5` | Memories considered per run |
| `recall_timeout` | `1.2` | Hard recall budget, seconds |
| `min_prompt_chars` | `8` | Skip recall for trivial prompts |
| `context_template` | built-in | `{context}` placeholder, brace-safe `.replace` rendering |
| `capture` | `True` | Persist the exchange after each run |
| `expose_search_tool` | `False` | Register memory tools on every run |
| `user_id_resolver` | `None` | `Callable[[AgentSession], str]` for dynamic identity |

## Development

```bash
pip install -e . agent-framework-core pytest pytest-asyncio
python -m pytest tests -q     # 21 tests incl. a REAL Agent run (stub chat client)
```

## License

MIT
