Metadata-Version: 2.5
Name: camel-memorysync
Version: 1.0.2
Summary: MemorySync memory for CAMEL agents: a lossless storage backend plus a drop-in AgentMemory with scored semantic recall and zero client-side embeddings.
Project-URL: Homepage, https://memorysync.io
Project-URL: Documentation, https://docs.memorysync.io/guides/camel-ai
Project-URL: Changelog, https://docs.memorysync.io/release-notes
Author-email: MemorySync <support@memorysync.io>
License-Expression: MIT
Keywords: agents,ai,camel,camel-ai,llm,memory,memorysync
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
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
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: <3.15,>=3.10
Requires-Dist: camel-ai>=0.2.60
Requires-Dist: httpx<1,>=0.25
Requires-Dist: mcp<2
Description-Content-Type: text/markdown

# camel-memorysync

MemorySync memory for [CAMEL](https://github.com/camel-ai/camel) agents.

Two pieces, use either or both:

- **`MemorySyncMemory`** — a drop-in `AgentMemory` for `ChatAgent(memory=...)`:
  verbatim chat history plus semantic recall from MemorySync, injected as one
  scored context record under a hard latency budget. Zero client-side
  embeddings.
- **`MemorySyncStorage`** — a **lossless** `BaseKeyValueStorage` for
  `ChatHistoryMemory` that mirrors user/assistant turns to MemorySync out of
  band.

```bash
pip install camel-memorysync
```

## Quickstart

```python
from camel.agents import ChatAgent
from camel_memorysync import MemorySyncMemory

memory = MemorySyncMemory(
    user_id="customer-42",      # required — who these memories belong to
    session_id="support",       # transcript scope
)
agent = ChatAgent(system_message="You are a helpful travel assistant.", memory=memory)

agent.step("I always prefer window seats on long flights")
# … days later, a new session:
agent.step("which seat should I book for the Oslo flight?")   # remembers
```

The API key comes from the `MEMORYSYNC_API_KEY` environment variable (or
`api_key=...`).

## Why not the in-repo Mem0 storage?

CAMEL ships `Mem0Storage` in its repo. Verified against its source:

| Behavior | Mem0 (`Mem0Storage`, in-repo) | **camel-memorysync** |
|---|---|---|
| History round-trip | ✗ **broken** — `load()` returns extracted facts, not your messages | byte-exact: `from_dict` reconstructs every record |
| Message roles | ✗ **every record hardcoded `role=USER`** — OpenAI alternation breaks | preserved exactly |
| `clear()` blast radius | ✗ calls **`client.delete_users()`** — the entire user entity | local window only; remote wipes are explicit (`forget_session()` / `forget_user()`) |
| `agent_id` filter | ✗ silently overwritten by `user_id` filter | both preserved per record |
| Failures | ✗ every exception swallowed — callers never know | conversation always works, failures logged loudly; explicit deletes raise |
| Multimodal | ✗ `image_list` / `video_bytes` silently discarded | full media round-trip (base64) |
| Recall latency guard | none | 1.2 s hard budget, fails open to history-only |
| Retried saves | duplicated | deterministic idempotency seeds converge |

`VectorDBMemory` (CAMEL's own long-term option) needs client-side embeddings —
`OpenAIEmbedding()` by default (extra key, cost, latency) plus a vector DB you
operate. Recall here is one MemorySync query; the index lives server-side.

## How recall enters the context

`ScoreBasedContextCreator` sorts records by timestamp. The recall block is one
SYSTEM-role record with `timestamp=0.0`, so it lands **right after the system
prompt** — your history is never reordered, rewritten, or role-swapped:

```text
[system]  You are a helpful travel assistant.
[system]  Relevant long-term memories about this user:
          - Prefers window seats on long flights
[user]    which seat should I book for the Oslo flight?
```

Memories created by **other MemorySync surfaces** (LangChain, the CLI, voice
agents, coding agents…) are recallable inside CAMEL too — that is the point of
memory-as-a-service.

## Storage-seam usage (ChatHistoryMemory)

```python
from camel.memories import ChatHistoryMemory, ScoreBasedContextCreator
from camel.types import ModelType
from camel.utils import OpenAITokenCounter
from camel_memorysync import MemorySyncStorage

memory = ChatHistoryMemory(
    context_creator=ScoreBasedContextCreator(OpenAITokenCounter(ModelType.GPT_4O_MINI), 2048),
    storage=MemorySyncStorage(user_id="customer-42", session_id="support"),
)
```

`save()` keeps verbatim records locally (exact round-trip) and mirrors
user/assistant turns to MemorySync; system prompts and tool chatter are never
shipped.

## Deletion — designed against data loss

| Call | What happens |
|---|---|
| `clear()` | resets the LOCAL conversation window only |
| `forget_session()` | deletes THIS session's mirrored turns (loud — failures raise) |
| `forget_user()` | deletes all **camel-surface** rows for this user; other surfaces' memories survive |

## Configuration

| Parameter | Default | Meaning |
|---|---|---|
| `user_id` | — (required) | End user the memories belong to |
| `session_id` | `default` | Transcript scope: `camel::<session>` |
| `top_k` | `5` | Memories per recall |
| `recall_timeout` | `1.2` | Hard recall budget (seconds) |
| `min_query_chars` | `8` | Skip recall for trivial topics |
| `window_size` | unlimited | History records per turn |
| `extraction` | `True` | Mirror turns to MemorySync |
| `context_creator` | ScoreBased/GPT-4o-mini/2048 | Any `BaseContextCreator` |

## Note on dependencies

`camel-ai` 0.2.x imports `FastMCP` from `mcp.server`, which `mcp` 2.0 moved —
an unpinned install crashes at `import camel.agents`. This package pins
`mcp<2` until CAMEL supports mcp 2.

## Tests

```bash
pip install -e . pytest
pytest tests -q   # 27 checks against the real camel-ai at latest
```

The suite drives a REAL `ChatAgent` turn via CAMEL's own `StubModel` and
reproduces each in-repo Mem0Storage bug as a regression test.

## License

MIT © MemorySync.
