Metadata-Version: 2.5
Name: strands-memorysync
Version: 1.0.0
Summary: MemorySync for Strands Agents: a MemoryStore with budgeted automatic recall before every model call, turn-by-turn duplicate-proof extraction, and a crash-proof initialize — zero framework dependencies.
Project-URL: Homepage, https://docs.memorysync.io/guides/strands
Project-URL: Documentation, https://docs.memorysync.io/guides/strands
Project-URL: Repository, https://github.com/memorysyncio/memorysync-plugins
Author-email: MemorySync <support@memorysync.io>
License-Expression: MIT
Keywords: agents,aws,long-term-memory,memory,memorysync,strands,strands-agents
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: httpx<1,>=0.25
Description-Content-Type: text/markdown

# strands-memorysync

[MemorySync](https://memorysync.io) for
[Strands Agents](https://github.com/strands-agents) (AWS's agent SDK):
automatic memory injection before every model call, duplicate-proof
turn-by-turn extraction, and a crash-proof lifecycle — with **zero
framework dependencies**.

```bash
pip install strands-memorysync
```

## Quick start

```python
from strands import Agent
from strands.memory import MemoryManager
from strands_memorysync import MemorySyncStore

store = MemorySyncStore(
    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(memory_manager=MemoryManager(stores=[store]))
agent("which seat should I book?")
```

The `MemoryManager` consults the store before **every** model call
(automatic injection — not tool-gated), and conversation turns persist
through the extraction sink.

## Why this one

| | Mem0 (`mem0_memory` tool in strands-tools) | Zep (`zep-strands` 0.1.0) | **MemorySync** |
| --- | --- | --- | --- |
| Automatic injection | ✗ tool-gated — the LLM must decide to recall | ✓ | ✓ |
| `initialize()` safety | — | ✗ **shipped an event-loop crash** (`RuntimeError: bound to a different event loop`; fix unreleased) | ✓ deliberately inert — a test asserts zero network calls |
| First-turn recall | — | ✗ 5-turn extraction lag: early recalls return nothing | ✓ turn-by-turn extraction works from the first exchange (idempotent writes make it safe) |
| Failure blast radius | sync client blocks the loop | ✗ store errors surface as unhandled `AggregateMemoryError` | ✓ search and extraction fail open; only explicit `add()` raises |
| Model-facing danger | ✗ exposes a **`delete` action** — one prompt injection wipes memories | — | ✓ search + save tools only; identity never model-facing |
| Data at rest | ✗ default FAISS path in `/tmp` — wiped on restart | cloud | ✓ MemorySync cloud |
| Framework pin | — | ✗ `strands-agents>=1.45` | ✓ **zero dependencies** (Protocol duck-typing) |
| Retry safety | ✗ duplicates | — | ✓ deterministic idempotency seeds |
| Python | — | ✗ ≥3.11 | ✓ ≥3.10 (matches the framework) |

## Semantics worth knowing

- Turns store verbatim under the `strands::<session>` transcript scope
  with deterministic seeds — manager retries and batch overlaps converge
  on one stored row.
- Tool/system messages are never persisted.
- `AddMessagesContext.sequence_numbers` are recorded in metadata for
  ordering.
- Free-tier quota exhaustion is silent by design (adds accepted-without-
  storing, reads empty); evaluation keys surface strict `429`s.
- `store.get_tools()` returns `memorysync_search` + `memorysync_save`
  (`@tool`-decorated) — enabled via the MemoryManager's tool config.

## Configuration

| Parameter | Default | Meaning |
| --- | --- | --- |
| `user_id` | — (required) | End user the memories belong to |
| `session_id` | `"default"` | Transcript scope |
| `top_k` | `5` | Memories considered per model call |
| `recall_timeout` | `1.2` | Hard recall budget, seconds |
| `min_prompt_chars` | `8` | Skip recall for trivial queries |
| `writable` | `True` | Allow the extraction sink to store turns |
| `extraction` | `True` | Strands extraction wiring (`{"cadence": 1}` recommended) |
| `expose_tools` | `True` | Return tools from `get_tools()` |

## Development

```bash
pip install -e . strands-agents pytest pytest-asyncio
python -m pytest tests -q     # 22 tests incl. a REAL Agent turn (stub Model)
```

## License

MIT
