Skip to content

Commit 1171055

Browse files
authored
feat(integrations): add AutoGen adapter + integration CI; fix broken adapters (#170)
Roadmap Phase 1, Week 3-4: Framework Adapters. New: AutoGen (AG2 / autogen-core v0.4+) adapter - mimir_autogen.MimirMemory implements the autogen_core.memory.Memory protocol (add/query/update_context/clear/close), maps MemoryContent onto Mimir entities, injects mimir_context as a SystemMessage before each turn - Persistent stdio session, pyproject, README, 7 passing tests (framework stubbed) Fixes uncovered while adding CI (no CI ran the Python tests before): - crewai + langgraph: init handshake read the wrong JSON-RPC id (req_id-1=0 vs init id 1), causing a 30s stall on every real session start. Now reads init_id - crewai + langgraph tests: FakePopen still used the old communicate() API after the adapters moved to persistent write/readline stdio — every test errored with 'FakePopen has no attribute stdin'. Rewrote both fakes to drive the stdio session - langgraph adapter passed nonexistent --ollama-url and misused --embedding-model (expects an ONNX path, not a model name). Now maps to --llm-endpoint/--llm-model New CI: .github/workflows/integrations.yml — matrix-tests all three adapters (autogen, crewai, langgraph) on every integrations/** change. langgraph installs the real package since it imports langgraph.store.base at module load. Verified: 7 (autogen) + 3 (crewai) + 6 (langgraph) = 16 tests passing locally.
1 parent b18952f commit 1171055

10 files changed

Lines changed: 1002 additions & 56 deletions

File tree

.github/workflows/integrations.yml

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
name: Integrations
2+
3+
on:
4+
push:
5+
branches: [main, master]
6+
paths:
7+
- "integrations/**"
8+
- ".github/workflows/integrations.yml"
9+
pull_request:
10+
branches: [main, master]
11+
paths:
12+
- "integrations/**"
13+
- ".github/workflows/integrations.yml"
14+
15+
jobs:
16+
test:
17+
runs-on: ubuntu-latest
18+
strategy:
19+
fail-fast: false
20+
matrix:
21+
include:
22+
# autogen & crewai tests stub their framework deps — no install needed.
23+
- adapter: autogen
24+
extra_deps: ""
25+
- adapter: crewai
26+
extra_deps: ""
27+
# langgraph adapter imports langgraph.store.base at module load,
28+
# so the real package must be present to collect the tests.
29+
- adapter: langgraph
30+
extra_deps: "langgraph"
31+
steps:
32+
- uses: actions/checkout@v4
33+
34+
- name: Set up Python
35+
uses: actions/setup-python@v5
36+
with:
37+
python-version: "3.11"
38+
39+
- name: Install test deps
40+
run: pip install pytest pytest-asyncio ${{ matrix.extra_deps }}
41+
42+
- name: Run ${{ matrix.adapter }} adapter tests
43+
working-directory: integrations/${{ matrix.adapter }}
44+
run: python -m pytest tests/ -v

integrations/README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,10 @@ Ready-to-use adapters that connect Mimir to popular AI agent frameworks.
77
| Framework | Type | Directory |
88
|---|---|---|
99
| **LangGraph** (LangChain) | `BaseStore` implementation | [`langgraph/`](langgraph/) |
10+
| **CrewAI** | Agent Tool | [`crewai/`](crewai/) |
11+
| **AutoGen** (AG2 / autogen-core) | `Memory` implementation | [`autogen/`](autogen/) |
1012
| **Claude Code** (Anthropic) | MCP server config | [`../docs/integration/claude-code.md`](../docs/integration/claude-code.md) |
1113
| **Cursor** | MCP server config | [`../docs/integration/cursor.md`](../docs/integration/cursor.md) |
12-
| **CrewAI** | Agent Tool | [`crewai/`](crewai/) |
1314

1415
## Adding a New Integration
1516

integrations/autogen/README.md

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
# Mimir for AutoGen
2+
3+
Persistent long-term memory for [AutoGen](https://github.com/microsoft/autogen)
4+
(AG2 / `autogen-core` v0.4+) agents, backed by [Mimir](https://github.com/Perseus-Computing-LLC/mimir).
5+
6+
`MimirMemory` implements the `autogen_core.memory.Memory` protocol, so it drops
7+
straight into an `AssistantAgent(memory=[...])`. Stored knowledge is injected
8+
into the model context before each inference, giving your agents memory that
9+
survives across sessions, processes, and crews.
10+
11+
## Install
12+
13+
```bash
14+
# Install Mimir (the binary)
15+
curl -sSL https://raw.githubusercontent.com/Perseus-Computing-LLC/mimir/main/scripts/bootstrap.sh | bash
16+
17+
# Install the adapter
18+
pip install -e integrations/autogen
19+
```
20+
21+
## Usage
22+
23+
```python
24+
import asyncio
25+
from autogen_agentchat.agents import AssistantAgent
26+
from autogen_ext.models.openai import OpenAIChatCompletionClient
27+
from mimir_autogen import MimirMemory
28+
29+
30+
async def main():
31+
memory = MimirMemory(db_path="~/.mimir/data/agent.db")
32+
33+
# Seed a fact
34+
from autogen_core.memory import MemoryContent, MemoryMimeType
35+
await memory.add(MemoryContent(
36+
content="The user prefers TypeScript over JavaScript.",
37+
mime_type=MemoryMimeType.TEXT,
38+
metadata={"category": "preferences", "key": "language"},
39+
))
40+
41+
agent = AssistantAgent(
42+
name="assistant",
43+
model_client=OpenAIChatCompletionClient(model="gpt-4o"),
44+
memory=[memory],
45+
)
46+
47+
result = await agent.run(task="What language should I use for this project?")
48+
print(result.messages[-1].content)
49+
50+
await memory.close()
51+
52+
53+
asyncio.run(main())
54+
```
55+
56+
## How it maps to Mimir
57+
58+
| AutoGen `Memory` method | Mimir tool | Behavior |
59+
|---|---|---|
60+
| `add(MemoryContent)` | `mimir_remember` | Content → `body_json`; `metadata.category`/`metadata.key` route the entity |
61+
| `query(text)` | `mimir_recall` | FTS5 keyword search → list of `MemoryContent` |
62+
| `update_context(ctx)` | `mimir_context` | Prepends the rendered memory block as a `SystemMessage` |
63+
| `clear()` | `mimir_prune` | Soft-deletes (archives) this memory's category |
64+
| `close()` || Shuts down the persistent Mimir stdio process |
65+
66+
## Configuration
67+
68+
```python
69+
MimirMemory(
70+
binary="mimir", # or absolute path: /usr/local/bin/mimir
71+
db_path="~/.mimir/data/mimir.db",
72+
category="autogen", # default category for add()
73+
context_limit=10, # entities injected by update_context()
74+
encryption_key="~/.mimir/secret.key", # optional AES-256-GCM at rest
75+
llm_endpoint="http://localhost:11434/api/generate", # optional, for hybrid search
76+
llm_model="nomic-embed-text", # optional embedding/RAG model
77+
)
78+
```
79+
80+
## Notes
81+
82+
- The adapter keeps a **persistent** Mimir stdio session — the process is
83+
spawned once and reused across all calls (no per-call cold start). Call
84+
`await memory.close()` when done, or let `__del__` reap it.
85+
- `add()` accepts `metadata={"category": ..., "key": ...}` to control where the
86+
entity lands. Without an explicit key, a timestamped key is generated so
87+
repeated `add()` calls never collide.
88+
- Use a **project-specific** `db_path` to isolate memories per agent or per
89+
workspace.

0 commit comments

Comments
 (0)