Migrate from AutoGen to OSYRA Memory (OME)
This guide maps AutoGen's Memory protocol and team message logs onto OSYRA Memory (OME) claims. AutoGen is an agent-framework memory-adapter migration, the same family as the LangGraph guide; read that guide first for the full reference, then read this one for the AutoGen-specific differences.
| Aspect | Value |
|---|---|
| Migration pattern | Agent-framework memory-adapter |
| Source scope | AutoGen Memory protocol implementations; per-team or per-group-chat |
| Source-side write access required | Yes — the adapter writes through Memory.add() going forward |
| Fidelity guarantees | Conversation reconstruction: message order preserved; speaker (agent) name preserved; tool-call outputs preserved as separate claims |
| Embedding policy | OME re-embeds |
| Rollback | Adapter-disable plus claim-revoke (see §8) |
§1 — Prerequisites
Source side (AutoGen)
- An AutoGen 0.4+ application using one of:
autogen_agentchat.agents.AssistantAgentwith theMemoryprotocol (the supported path)autogen_agentchat.teams.RoundRobinGroupChat/SelectorGroupChat(multi-agent teams)
- A supported
Memoryprotocol implementation:autogen_core.memory.ListMemory(in-process, ephemeral)autogen_core.memory.ChromaDBVectorMemory(delegates to ChromaDB; see also the ChromaDB guide)- Custom
Memoryimplementations: the adapter is interface-compatible, but the back-fill ships only common-case readers.
- For multi-agent setups: the list of agent names (so role tagging is correct).
- For team-based setups: the team or group-chat ID.
- AutoGen 0.4.x or later (the older 0.2.x
ConversableAgentAPI is significantly different and out of scope).
OSYRA side (OME)
Identical to the LangGraph prerequisites. Naming conventions:
- Suggested runtime signer DID:
did:osyra:ws:<uuid>:signer:agent-autogen-<deployment-id>. - Suggested runtime tag:
autogen:<deployment-id>:team:<team-id>:agent:<agent-name>, orautogen:<deployment-id>:agent:<agent-name>for single-agent setups.
Credential handling
Supply credentials through environment variables sourced from a secret store, never as command-line flags.
§2 — Source-system schema (AutoGen)
AutoGen 0.4 organizes data via the Memory protocol, which has two flavors.
Per-agent memory (single-agent)
| Source field | Source type | Treatment |
|---|---|---|
| MemoryContent.content | string or list[dict] (multimodal) | The body field — text concatenated; non-text logged to skipped |
| MemoryContent.mime_type | enum (TEXT, MARKDOWN, JSON, IMAGE) | TEXT and MARKDOWN handled; JSON serialized to body; IMAGE skipped |
| MemoryContent.metadata | dict[str, Any] | Passthrough into claim.metadata.source_metadata.* |
| (derived) agent name | string | Becomes claim.metadata.agent_name and a tag suffix |
Team conversations (multi-agent)
AutoGen teams produce ChatMessage sequences with an additional speaker attribution.
| Source field | Source type | Treatment |
|---|---|---|
| BaseChatMessage.content | string or list[dict] | The body field |
| BaseChatMessage.source | string (the agent that spoke) | Becomes claim.metadata.role (as agent:<name>) |
| BaseChatMessage.type | enum (TextMessage, ToolCallRequestEvent, ToolCallExecutionEvent, and others) | Determines claim type (see §3) |
| BaseChatMessage.models_usage | RequestUsage (tokens) | Becomes claim.metadata.tokens_in/out |
| (derived) team ID + turn index | string + int | Tag + message_seq |
Concepts that are not preserved
| Source concept | Why not preserved | Implication | |---|---|---| | Agent system messages (the configuration prompt) | Configuration, not memory | None | | Tool definitions (the schemas) | Configuration, not memory | Only tool calls and results are memory | | Termination conditions | Control flow, not memory | None | | Streaming events (token-level) | Only complete messages are captured | If you stream, the adapter waits |
§3 — OSYRA target mapping
The mapping follows the same shape as the LangGraph mapping. AutoGen-specific deltas:
Per-message mapping
| Source message type | Claim type | metadata.role | Body source |
|---|---|---|---|
| TextMessage (from an agent) | memory.observation | agent:<source> | .content |
| TextMessage (from a user / human-in-the-loop) | memory.observation | human | .content |
| MultiModalMessage | memory.observation | (per source) | .content text blocks only; image blocks → metadata.source_attachments (URLs/refs only) |
| ToolCallRequestEvent | memory.observation (one) + memory.fact (per tool call) | agent:<source> (observation) + tool:<tool_name> (each fact) | Observation: empty; facts: tool args JSON |
| ToolCallExecutionEvent | memory.fact | tool:<tool_name> | Tool result content |
| StopMessage | memory.observation | system | Reason string |
| HandoffMessage (team coordination) | memory.observation | system | Handoff target + reason |
Tag schema
- Single-agent:
autogen:<deployment-id>:agent:<agent-name>. - Team:
autogen:<deployment-id>:team:<team-id>(per-agent role still captured inmetadata.role).
Adapter interface (Python)
The osyra-autogen package ships two adapter shims, one per AutoGen abstraction.
OsyraMemory is a drop-in for the Memory protocol:
from autogen_core.memory import ListMemory
from osyra_autogen import OsyraMemory
inner_memory = ListMemory()
memory = OsyraMemory(
inner=inner_memory,
workspace_id="ws_abc123",
signer_did="did:osyra:ws:abc123:signer:agent-autogen-prod",
deployment_id="prod-deployment-1",
agent_name="researcher",
)
agent = AssistantAgent(
name="researcher",
model_client=...,
memory=[memory],
)OsyraTeamMessageObserver captures team-level messages:
from autogen_agentchat.teams import RoundRobinGroupChat
from osyra_autogen import OsyraTeamMessageObserver
observer = OsyraTeamMessageObserver(
workspace_id="ws_abc123",
signer_did="did:osyra:ws:abc123:signer:agent-autogen-prod",
deployment_id="prod-deployment-1",
team_id="research-team",
)
team = RoundRobinGroupChat(
participants=[researcher, critic, planner],
termination_condition=...,
)
team.add_message_observer(observer)Override flags (CLI back-fill)
The general shape matches LangGraph, with AutoGen-specific flags:
| Flag | Default | Effect |
|---|---|---|
| --source-memory-type <type> | auto | list, chromadb, or custom; controls the back-fill reader |
| --team-id <id> | (none) | For team-based back-fill |
| --agent-name <name> | (none) | For single-agent back-fill |
| --include-tool-events | true | Whether to expand tool-call events into separate fact claims |
§4 — CLI walkthrough
Dry-run
export OSYRA_WORKSPACE_ID="ws_abc123"
export OSYRA_SIGNER_DID="did:osyra:ws:abc123:signer:migration"
osyra migrate autogen \
--source-memory-type chromadb \
--source-chromadb-persist-dir ./autogen-memory/ \
--deployment-id prod-deployment-1 \
--agent-name researcher \
--dry-runTeam back-fill
osyra migrate autogen \
--source-memory-type list \
--source-team-state ./autogen-state.json \
--deployment-id prod-deployment-1 \
--team-id research-team \
--output-dir ./autogen-team-migrate/Deploy the runtime adapter
See §3 for the per-agent and per-team adapter usage. The deployment order is identical to the LangGraph walkthrough.
§5 — Expected output
osyra-migrate autogen
Workspace: ws_abc123
Signer DID: did:osyra:ws:abc123:signer:migration
Source memory: chromadb (./autogen-memory/)
Deployment ID: prod-deployment-1
Agent: researcher
Memory items: 2,847
Batch size: 1000
Bundles planned: 3
Output dir: ./autogen-migrate-full/
[1/3] Extracting batch ... 1000/1000 items
[1/3] Building claims ... 1000/1000 claims (0 skipped)
[1/3] Signing bundle ... CID: bafy2bzaceabc...001
[1/3] Imported bundle ... 1000/1000 claims accepted
...
Summary:
Total observation claims: 2,847
Total fact claims: 0 (single-agent memory; no tool calls in ListMemory)
Total claims: 2,847
Total bundles: 3For team back-fill, the output additionally reports per-agent contribution counts:
By agent:
researcher: 1,124 messages
critic: 892 messages
planner: 831 messages§6 — Caveats
1. Two adapter shims (per-agent and per-team)
AutoGen has two distinct integration points: per-agent Memory and per-team message observation. Decide which one you need before deploying.
- If your application has agents with attached
Memoryand you care about that memory: useOsyraMemory. - If your application is a team conversation and you care about the team's message log: use
OsyraTeamMessageObserver. - If both: deploy both. The tags differ (
autogen:...:agent:<name>vsautogen:...:team:<id>), so they do not collide.
2. Multimodal handling is text-only
MultiModalMessage contains a list of content blocks (text and image). Text is extracted and images are skipped, with a metadata.source_attachments entry listing the image URLs/refs. If your agents do significant vision work, this is a lossy migration for those messages.
3. ChromaDB-backed memory
If your Memory is backed by ChromaDB (autogen_core.memory.ChromaDBVectorMemory), the back-fill CLI delegates to the ChromaDB migration path internally. The decision rule for metadata.source:
| Invocation | metadata.source | Tag prefix |
|---|---|---|
| osyra migrate chromadb directly against a raw ChromaDB collection (even one used by an AutoGen agent) | chromadb | chromadb:<collection> |
| osyra migrate autogen where the agent's Memory is backed by ChromaDB (AutoGen back-fill delegates internally) | autogen | autogen:<deployment-id>:agent:<agent-name> |
Choose the entry point based on how you think about the data: a raw vector store → chromadb; an agent memory layer → autogen. The schema-mapping logic is shared, but the provenance attribution differs.
4. ListMemory is ephemeral
autogen_core.memory.ListMemory is in-process. Back-fill applies only if the application is currently running and you can serialize the memory state to a structured format. The CLI ships a helper that uses Memory.query() to enumerate items and writes them to a JSON intermediate file (see the team back-fill step in §4). JSON is the only supported intermediate format. Otherwise, adapter-only deployment is the only meaningful path.
5. Speaker attribution
AutoGen requires the speaker's agent name to flow into metadata.role. If you have multiple agents with the same name in different teams, you get tag-overlap on the role distinguisher — use unique agent names within a workspace.
6. Sequencing, idempotency, GDPR, adapter signer custody
These behave identically to LangGraph — see the LangGraph caveats.
§7 — Round-trip verification
The protocol is the same as the LangGraph verification protocol, with these substitutions:
- LangGraph thread ID → AutoGen team ID (team-level) or agent name (per-agent).
state.messages→ AutoGenMemory.query()results (per-agent) or the team'smessageslog (team-level).- Per-message claim count: one per
TextMessage;1 + Nfor aToolCallRequestEventwith N tool calls.
AutoGen-specific spot-check
For teams, verify the metadata.role agent-name distribution matches your team configuration. A team of three agents should produce claims with three distinct metadata.role values (plus human if there is a human-in-the-loop participant).
Acceptance criterion
At least 99.5% of sampled conversations have an exact claim-count match.
§8 — Rollback
The structure is identical to the LangGraph rollback: adapter-disable, then selective claim-revoke, then back-fill rollback. The AutoGen adapter is removed by:
- Per-agent: remove
OsyraMemoryfrom the agent'smemorylist and use the innerMemorydirectly. - Per-team: remove the
OsyraTeamMessageObserverfrom the team.
Re-deploy the application. Otherwise identical — the 24-hour observation window applies and the source AutoGen state is untouched.
§9 — Troubleshooting
1. Both per-agent and per-team adapters installed; claims duplicated
- Symptom: verification finds each message represented as two claims, with the same
bodycontent but different tags. - Likely cause: you deployed both
OsyraMemory(on the agent) andOsyraTeamMessageObserver(on the team that includes that agent). Both capture the message. - Diagnostic:
osyra ome list-by-tagon each of the two tags and look for duplicatebodycontent. - Fix: choose one integration point. The per-team observer covers single-agent setups too (via a team of one); prefer it unless you have a specific per-agent memory use case.
2. MultiModalMessage with images lost
- Symptom: verification finds
claim.bodyshorter than theBaseChatMessage.contentrepr. - Likely cause:
contentwas a list with text and image blocks; only the text was extracted. - Diagnostic: sample a
MultiModalMessage:isinstance(msg.content, list)and inspect. - Fix: this is documented behavior.
metadata.source_attachmentscontains the image URL refs as an audit trail.
3. Tool-call events expanded unexpectedly
- Symptom: the tool-call claim count is higher than expected — a
ToolCallRequestEventwith one tool call produces three claims instead of two. - Likely cause: the follow-up
ToolCallExecutionEventwas also emitted, or the tool call had a nested tool call (a handoff). - Diagnostic: count distinct
tool_call_idvalues across bothToolCallRequestEventandToolCallExecutionEventfor that turn. - Fix: this is correct behavior. Per tool call: 1 observation + 1 args fact (from the request) + 1 result fact (from the execution) = 3 claims. Recalibrate expectations.
4. Signer DID not authorized
Same as LangGraph — see the LangGraph signer-DID troubleshooting. Grant-expiry, Proof-of-Possession, and cache-miss causes apply identically.
5. Adapter buffer growing
Same as LangGraph — see the LangGraph adapter-buffer troubleshooting.