Metadata-Version: 2.5
Name: chatdev-memorysync
Version: 1.1.0
Summary: MemorySync memory store for ChatDev 2.0 (DevAll): type: memorysync in workflow YAML — semantic recall with budgets, honest timestamps, fact extraction from the user's input, and idempotent writes.
Project-URL: Homepage, https://memorysync.io
Project-URL: Documentation, https://docs.memorysync.io/guides/chatdev
Project-URL: Changelog, https://docs.memorysync.io/release-notes
Author-email: MemorySync <support@memorysync.io>
License-Expression: MIT
Keywords: agents,ai,chatdev,devall,llm,memory,memorysync,openbmb
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.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.12
Requires-Dist: httpx<1,>=0.25
Description-Content-Type: text/markdown

# chatdev-memorysync

MemorySync memory store for [ChatDev 2.0 (DevAll)](https://github.com/OpenBMB/ChatDev) — OpenBMB's zero-code multi-agent platform.

One pip install adds `type: memorysync` to ChatDev's memory registry: usable
from workflow YAML **and** the web console's store-type dropdown, no code
changes to ChatDev required.

```bash
# inside your ChatDev checkout's environment
uv pip install chatdev-memorysync     # or: pip install chatdev-memorysync
```

Activation is automatic (a `.pth` hook registers the store whenever ChatDev's
modules are importable, and silently no-ops anywhere else). The explicit
alternative:

```python
import chatdev_memorysync
chatdev_memorysync.register()
```

## Workflow YAML

```yaml
graph:
  nodes:
    - id: writer
      type: agent
      config:
        # ... model config ...
        memories:
          - name: user_memory
            top_k: 5
            retrieve_stage: [gen]
            read: true
            write: true
  memory:
    - name: user_memory
      type: memorysync
      config:
        api_key: ${MEMORYSYNC_API_KEY}
        user_id: customer-42        # REQUIRED — who these memories belong to
        session_id: support         # optional session label
```

Retrieved memories arrive in the standard `===== Related Memories =====`
block ChatDev injects into agent prompts.

## What gets stored

After each agent node that writes to the store (`write: true`, ChatDev's
default) runs, the store sends that node's input — the request it received,
with ChatDev's `=== INPUT FROM … ===` pipeline headers stripped — to
MemorySync as the user's turn. MemorySync extracts the durable facts in it
(preferences, constraints, details about the user) and only those facts
become memories. The input text itself is not stored.

- Agent outputs are not stored as memories, so they are never sent.
  `store_outputs` is still accepted in workflow YAML and has no effect.
- A retry or re-run of the same input in the same session is recognised
  server-side and extracted once.
- Facts carry `surface: chatdev`, your `session_id`, and `role: input`.
  The input's attachment overview travels with the request, but facts keep
  only plain (scalar) metadata, so attachment lists are not stored on them.
- Inputs under 3 characters are skipped; inputs over 16,000 characters are
  truncated before they are sent.

A downstream node's input is what the upstream nodes produced, and it is sent
the same way. To learn only from the user's own words, keep `write: true` on
the node that receives the user's request and set `write: false` on the
others (they can still `read`).

## Why this instead of the in-tree Mem0 store?

ChatDev ships a `mem0` store in its repo. Verified against its source:

| Behavior | Mem0 (in-tree store) | **memorysync** |
|---|---|---|
| User scoping | ✗ demo YAML hardcodes `user_id: project-user-123` — every operator shares one partition | `user_id` is a REQUIRED config field |
| Slow/down backend | ✗ SDK call with **no timeout** — the whole agent turn stalls | hard `recall_timeout` budget (1.2 s), fails open to no memories |
| Timestamps | ✗ every retrieved item stamped `time.time()` — **corrupts ChatDev's own time-decay scorer** (0.7 of ranking weight) and unfairly outranks honest stores | the row's real `created_at` |
| Retries / re-runs | ✗ duplicate extractions on every re-send | deterministic speaker seeds — a re-sent input is recognised server-side and extracted once |
| Failure diagnosis | ✗ bare `logger.error` + `[]` — quota, auth, and network all look like "no memories" | fail-open logs carry the HTTP status code |

Facts extracted here are recallable from **every other MemorySync surface**
(LangChain, the CLI, voice agents, Dify…) and vice versa.

## Configuration

| Field | Default | Meaning |
|---|---|---|
| `api_key` | `${MEMORYSYNC_API_KEY}` | MemorySync API key |
| `user_id` | — (required) | End user the memories belong to |
| `session_id` | `chatdev` | Session label, recorded on the extracted facts as `session_id` |
| `base_url` | `https://api.memorysync.io` | Override for staging |
| `recall_timeout` | `1.2` | Hard recall budget in seconds |
| `store_outputs` | `false` | Accepted for existing workflows; has no effect (agent outputs are not stored as memories) |
| `source` | `chatdev` | Source label on the extracted facts |

Per-agent knobs (`top_k`, `similarity_threshold`, `read`, `write`,
`retrieve_stage`) come from ChatDev's own `memories:` attachment config and
are honored — including `similarity_threshold` filtering on real scores.

## Tests

```bash
git clone --depth 1 https://github.com/OpenBMB/ChatDev.git chatdev
pip install -e . pytest pydantic openai pyyaml tenacity numpy faiss-cpu fastmcp jinja2
pytest tests -q   # 38 checks against the real ChatDev 2.0 modules
```

The suite drives ChatDev's real config parser, registry, `MemoryFactory`,
and `MemoryManager` — and reproduces each in-tree Mem0 store bug as a
regression test.

## License

MIT © MemorySync.
