Multi-agent frameworks
Multi-Agent Framework Patterns — Structural Survey
Section titled “Multi-Agent Framework Patterns — Structural Survey”Audience: Wes, designing 6-18 variant agent fleet
Question: What folder/file structure do production multi-agent frameworks use? Does anything resemble Active/Reference/Logs/Archive?
Method: Pulled docs + actual GitHub example trees for each framework. Citations inline.
Date: 2026-05-11
TL;DR — The Convergent Pattern
Section titled “TL;DR — The Convergent Pattern”Every production framework converges on roughly the same layout:
project-root/├── src/<package>/│ ├── agents/ # one file per agent (persona + tools + model)│ ├── tools/ # one file per tool, shared across agents│ ├── workflows/ # orchestration / graphs / flows│ ├── config/ # YAML/JSON declarative configs (optional)│ ├── state.py # shared schema (LangGraph) or memory blocks (Letta)│ └── index.ts | main.py # wire-up entry point├── knowledge/ | data/ # static reference docs (optional)├── tests/├── .env.example└── package.json | pyproject.toml | langgraph.json | mastra configWes’s Active/Reference/Logs/Archive pattern: NO framework recommends it as a code-organization scheme. What every framework DOES recommend is splitting by role/responsibility (agents, tools, workflows, config) — i.e., what a thing IS, not what its lifecycle state is.
That said, the Active/Archive lifecycle distinction maps cleanly to a separate dimension that frameworks handle outside the code tree: D1/database state, vault notes, transcript logs. Wes’s pattern is reinventing what these frameworks push to runtime stores. Specifics in the verdict section.
Framework 1: LangGraph
Section titled “Framework 1: LangGraph”Source: docs.langchain.com/oss/python/langgraph/application-structure + github.com/langchain-ai/new-langgraph-project + react-agent template
1. Single agent definition
Section titled “1. Single agent definition”One Python file. Default template puts the whole agent in src/<pkg>/graph.py as a compiled StateGraph. The richer react-agent template splits it into graph.py + state.py + tools.py + prompts.py + context.py + utils.py.
2. Multiple agents organization
Section titled “2. Multiple agents organization”No subfolder-per-agent convention. Multi-agent systems are expressed as nodes in a graph, not as files. Each agent is a function (or sub-graph) added with builder.add_node("agent_name", agent_fn). The langgraph-supervisor library deprecates folder splitting in favor of supervisor agents using tool-handoff. (langgraph-supervisor-py README)
3. Shared knowledge / context
Section titled “3. Shared knowledge / context”StateGraph(TypedDict) schema — a single shared dict that all nodes read/write. Reducers (Annotated[str, operator.add]) merge concurrent updates. Subgraphs can have private state keys plus shared keys with the parent. (langgraph state docs)
4. Identity persistence across sessions
Section titled “4. Identity persistence across sessions”Checkpointer pattern — MemorySaver, SqliteSaver, PostgresSaver, RedisSaver. State is serialized per thread_id. There is no agent-identity-file; identity = thread_id + checkpointer.
5. Recommended structure (canonical, from new-langgraph-project)
Section titled “5. Recommended structure (canonical, from new-langgraph-project)”my-app/├── src/│ └── agent/│ ├── __init__.py│ └── graph.py # the only required file├── tests/│ ├── integration_tests/│ └── unit_tests/├── .env.example├── langgraph.json # registers graphs + deps├── pyproject.toml└── Makefilereact-agent variant (more realistic):
my-app/├── src/│ └── react_agent/│ ├── __init__.py│ ├── graph.py # wire nodes/edges│ ├── state.py # TypedDict schema│ ├── tools.py # tool fns│ ├── prompts.py # system prompts│ ├── context.py # runtime config│ └── utils.py├── tests/├── langgraph.json└── pyproject.toml6. Specialization from shared base
Section titled “6. Specialization from shared base”Agents share the same model instance and tool registry; specialization happens by:
- Different
system_messageper node - Different subset of tools passed to
create_react_agent(model, tools=[...]) - Different sub-graph compiled per agent role
Framework 2: CrewAI
Section titled “Framework 2: CrewAI”Source: docs.crewai.com + github.com/crewAIInc/crewAI-examples + CLI crewai create crew
1. Single agent definition
Section titled “1. Single agent definition”Split: YAML + Python decorator. Persona/role/goal/backstory in agents.yaml. Tools and behavior wiring in crew.py via @agent decorator that references the YAML key.
lead_market_analyst: role: Lead Market Analyst goal: Conduct amazing analysis of products and competitors backstory: As the Lead Market Analyst...@agentdef lead_market_analyst(self) -> Agent: return Agent(config=self.agents_config['lead_market_analyst'], tools=[SerperDevTool(), ScrapeWebsiteTool()], verbose=True, memory=False)2. Multiple agents organization
Section titled “2. Multiple agents organization”ALL agents in one YAML file. agents.yaml is a flat dict keyed by agent name. Same for tasks.yaml. Multiple crews in one project go into src/<pkg>/crews/<crew_name>/ (the Flow pattern).
3. Shared knowledge / context
Section titled “3. Shared knowledge / context”knowledge/top-level folder for files agents can read (PDFs, txts).memory=Trueon crew enables shared short/long-term memory via ChromaDB.- Inputs flow through
crew.kickoff(inputs={...}).
4. Identity persistence across sessions
Section titled “4. Identity persistence across sessions”CrewAI Memory module: short-term (RAG of recent context), long-term (SQLite at ~/.crewai/), entity memory. trained_agents_data.pkl stores DPO-style training from crew.train(). No per-agent identity file beyond the YAML.
5. Recommended structure (canonical, from crewai create crew)
Section titled “5. Recommended structure (canonical, from crewai create crew)”Single crew:
my_crew/├── src/│ └── my_crew/│ ├── __init__.py│ ├── main.py # entry point│ ├── crew.py # @CrewBase class wiring agents + tasks│ ├── config/│ │ ├── agents.yaml # ALL agents│ │ └── tasks.yaml # ALL tasks│ └── tools/│ ├── __init__.py│ └── custom_tool.py├── knowledge/ # static reference docs├── .env├── pyproject.toml└── README.mdFlow with multiple crews (real example from flows/email_auto_responder_flow):
my_flow/├── src/│ └── my_flow/│ ├── main.py # Flow orchestration│ ├── types.py # Shared Pydantic models│ ├── crews/│ │ └── email_filter_crew/│ │ ├── config/│ │ │ ├── agents.yaml│ │ │ └── tasks.yaml│ │ └── email_filter_crew.py│ ├── tools/│ └── utils/└── pyproject.toml6. Specialization from shared base
Section titled “6. Specialization from shared base”- Tools are imported per-agent in
crew.py(no global “all agents have X”). - YAML inheritance is not native — duplication is the norm.
- Hierarchical mode adds a manager agent automatically.
Framework 3: AutoGen (Microsoft)
Section titled “Framework 3: AutoGen (Microsoft)”Source: github.com/microsoft/autogen/python/samples + autogen-studio
1. Single agent definition
Section titled “1. Single agent definition”Pure Python class. AssistantAgent(name="x", model_client=..., system_message="...", tools=[...]). No file convention — agents are instantiated inline.
2. Multiple agents organization
Section titled “2. Multiple agents organization”Convention is “all agents in one file” for simple samples, split-by-runtime for distributed. The core_distributed-group-chat sample is the most structured:
core_distributed-group-chat/├── _agents.py # ALL agent classes (BaseGroupChatAgent, etc.)├── _types.py # Shared message types├── _utils.py # Shared helpers├── config.yaml # Model config├── run_host.py # gRPC host process├── run_group_chat_manager.py├── run_editor_agent.py # ONE FILE PER RUNTIME (when distributed)├── run_writer_agent.py├── run_ui.py└── public/avatars/ # Per-agent assets ├── editor.png └── writer.pngNote: when agents run as separate processes (gRPC), each gets its own run_<name>.py launcher. This is the closest the survey gets to “folder per variant.”
3. Shared knowledge / context
Section titled “3. Shared knowledge / context”GroupChatkeeps the shared message history in memory.task_centric_memorysample uses a separate memory store.- Topic-based pub/sub in distributed mode.
4. Identity persistence across sessions
Section titled “4. Identity persistence across sessions”Weak. AutoGen agents are mostly stateless in their core; persistence is opt-in via custom Memory implementations. autogen-studio saves team configs as JSON.
5. Recommended structure
Section titled “5. Recommended structure”No CLI scaffolder. Manual. The distributed sample above is the de-facto reference.
6. Specialization from shared base
Section titled “6. Specialization from shared base”Subclass BaseGroupChatAgent (seen in _agents.py). All inherit _chat_history, _model_client, _system_message. Override handle_request_to_speak for role-specific behavior.
Framework 4: Mastra (TypeScript)
Section titled “Framework 4: Mastra (TypeScript)”Source: mastra.ai/docs/getting-started/project-structure + github.com/mastra-ai/mastra/examples
1. Single agent definition
Section titled “1. Single agent definition”One TypeScript file per agent: src/mastra/agents/weather-agent.ts. Exports a named Agent instance with model, instructions, tools, memory wired inline.
2. Multiple agents organization
Section titled “2. Multiple agents organization”One file per agent, all in src/mastra/agents/. Then re-exported from src/mastra/agents/index.ts and registered in src/mastra/index.ts. The real examples/agent sample has this:
src/mastra/agents/├── index.ts # barrel re-export├── dynamic-tools-agent.ts├── gateway.ts├── model-v2-agent.ts├── request-context-demo-agent.ts└── slack-agent.tssrc/mastra/index.ts then imports and registers them all on the Mastra constructor.
3. Shared knowledge / context
Section titled “3. Shared knowledge / context”@mastra/memory— per-agent working memory + semantic recall via LibSQL/Postgres/Upstash.- Workflows pass context through typed steps.
- MCP servers (
src/mastra/mcp/) expose tools to external agents.
4. Identity persistence across sessions
Section titled “4. Identity persistence across sessions”LibSQL/Postgres store via MastraCompositeStore. Threads + messages persisted per agent. Agent ID is its export name.
5. Recommended structure (canonical from create mastra CLI)
Section titled “5. Recommended structure (canonical from create mastra CLI)”my-app/├── src/│ ├── mastra/│ │ ├── agents/│ │ │ └── weather-agent.ts│ │ ├── tools/│ │ │ └── weather-tool.ts│ │ ├── workflows/│ │ │ └── weather-workflow.ts│ │ ├── scorers/ # optional: eval scorers│ │ │ └── weather-scorer.ts│ │ ├── mcp/ # optional: custom MCP servers│ │ ├── public/ # optional: copied to build output│ │ └── index.ts # Mastra config (REQUIRED)│ └── index.ts # app entry├── .env.example├── package.json└── tsconfig.jsonReal example structure (examples/agent) adds:
src/mastra/├── agents/ # 5 agents, one file each├── auth/ # auth providers (better-auth, okta, workos, ...)├── mcp/ # MCP servers + app-tools├── processors/ # content filters (PII detection, moderation)├── tools/├── workflows/ # multi-step workflows└── index.ts6. Specialization from shared base
Section titled “6. Specialization from shared base”- Tools imported per-agent in the agent’s file.
- A “supervisor agent” pattern:
supervisorAgentreferences other agents as tools viaagentTool(). - Shared model client / shared memory store passed into each
new Agent({...}).
Framework 5: Pydantic AI
Section titled “Framework 5: Pydantic AI”Source: ai.pydantic.dev + github.com/pydantic/pydantic-ai/examples
1. Single agent definition
Section titled “1. Single agent definition”Either:
- Inline Python:
agent = Agent('openai:gpt-4o', instructions='...', output_type=Foo) - Declarative YAML (newer feature):
agent.yamlwith model, instructions, capabilities. Loaded viaAgent.from_file('agent.yaml').
model: anthropic:claude-opus-4-6instructions: You are a helpful research assistant.model_settings: max_tokens: 8192capabilities: - WebSearch - Thinking: effort: high2. Multiple agents organization
Section titled “2. Multiple agents organization”One Python file = one whole multi-agent system in the example repo. medical_agent_delegation.py defines triage_agent, cardiology_agent, neurology_agent, senior_doctor_agent all in the same file. Delegation via @agent.tool functions that call other agents.
For real apps the slack_lead_qualifier example splits by responsibility, not by agent:
slack_lead_qualifier/├── __init__.py├── agent.py # ALL agents here├── app.py # FastAPI app├── functions.py # business logic├── models.py # Pydantic models├── modal.py # deployment├── slack.py # Slack integration└── store.py # persistence3. Shared knowledge / context
Section titled “3. Shared knowledge / context”RunContext[Deps] — a typed dependency container. Agents receive a shared Deps dataclass with DB connections, API clients, user info.
4. Identity persistence across sessions
Section titled “4. Identity persistence across sessions”Built-in message_history parameter on Agent.run(). Pydantic AI ships pydantic_graph for stateful flows. No automatic identity file.
5. Recommended structure
Section titled “5. Recommended structure”No CLI scaffold. The official example layout is the closest thing:
my-app/├── my_app/│ ├── __init__.py│ ├── agent.py # one or many agents│ ├── models.py # Pydantic output schemas│ ├── functions.py # @agent.tool implementations│ ├── store.py # persistence│ └── app.py # web/API entry├── tests/└── pyproject.toml6. Specialization from shared base
Section titled “6. Specialization from shared base”Agents share the Deps type and base model. Each agent declares its own output_type (Pydantic model) and system_prompt. Tools are decorated per-agent: @triage_agent.tool vs @senior_doctor_agent.tool.
Framework 6: Letta (MemGPT)
Section titled “Framework 6: Letta (MemGPT)”Source: docs.letta.com + github.com/letta-ai/letta
1. Single agent definition
Section titled “1. Single agent definition”Agents are server-side objects, not files. Created via API: client.agents.create(model="...", memory_blocks=[...], tools=[...]). Returns an agent_id.
That said, Letta DOES ship a file-based persona convention from its MemGPT roots:
letta/├── personas/examples/│ ├── sam.txt│ ├── memgpt_starter.txt│ ├── google_search_persona.txt│ ├── sleeptime_memory_persona.txt│ └── voice_memory_persona.txt└── humans/examples/ ├── basic.txt └── cs_phd.txtOne .txt file = one persona block. Loaded into a memory_block at agent creation.
2. Multiple agents organization
Section titled “2. Multiple agents organization”Server-managed. Listed via client.agents.list(). No local file convention beyond personas/ + humans/.
3. Shared knowledge / context
Section titled “3. Shared knowledge / context”Memory Blocks API — standalone, attachable to multiple agents:
block = client.blocks.create( label="company_info", value="Acme Corp...", tags=["shared", "company"])client.agents.blocks.attach(agent_id=..., block_id=block.id)Plus Folders (formerly “sources”) — collections of files (PDFs, .txt) attached to an agent for vector search. Same folder can attach to multiple agents.
4. Identity persistence across sessions
Section titled “4. Identity persistence across sessions”This is Letta’s headline feature. Every agent has:
- Core memory blocks (persona, human, custom) — always in context, editable by the agent itself
- Archival memory — vector store, unlimited, semantic search
- Recall memory — full message history
- Agent state persisted in Postgres
agent_id is the durable identity. Sessions resume by passing the same ID.
5. Recommended structure
Section titled “5. Recommended structure”No app-side scaffold — Letta is server-first. Client apps look like:
my-app/├── personas/ # optional: .txt persona library│ ├── researcher.txt│ └── writer.txt├── humans/ # optional: user profiles│ └── wes.txt├── src/│ ├── client.py # letta_client setup│ ├── bootstrap.py # one-time agent creation│ └── handlers.py # message routing└── .env6. Specialization from shared base
Section titled “6. Specialization from shared base”- Shared memory blocks (one block, many agents).
- Shared folders (one knowledge source, many agents).
- Per-agent persona block + tool list.
- Letta Cloud has “agent templates” you can clone.
Framework 7: Mem0
Section titled “Framework 7: Mem0”Source: docs.mem0.ai + github.com/mem0ai/mem0
Not a multi-agent framework — it’s a memory layer
Section titled “Not a multi-agent framework — it’s a memory layer”Mem0 is the persistence backbone you bolt onto another framework. No project scaffold.
Memory hierarchy (this IS the interesting structural pattern)
Section titled “Memory hierarchy (this IS the interesting structural pattern)”graph LR A[Conversation turn] --> B[Session memory] B --> C[User memory] C --> D[Org memory]Scoping identifiers:
user_id— long-term per-user (preferences, history)agent_id— agent-specific knowledgeapp_id— app-level isolation (multi-tenant)run_id— session-scoped (ephemeral, deletable on session end)
Usage pattern:
# User-level: persistent preferencesclient.add(messages, user_id="alice")
# Session-level: temporary contextclient.add(messages, user_id="alice", run_id="session_123")
# Agent-level: agent-specific knowledgeclient.add(messages, agent_id="support_bot", app_id="helpdesk")
# Multi-tenant: full isolationclient.add(messages, user_id="alice", agent_id="bot", app_id="acme_corp", run_id="ticket_42")Key insight: the lifecycle dimension (session vs persistent) lives in runtime scopes, NOT folder structure. Sessions are tagged-and-deletable, not archived-on-disk.
Cross-Framework Patterns
Section titled “Cross-Framework Patterns”CONVERGENT (strong signals — every framework does this)
Section titled “CONVERGENT (strong signals — every framework does this)”| Pattern | LangGraph | CrewAI | AutoGen | Mastra | PydanticAI | Letta |
|---|---|---|---|---|---|---|
src/<pkg>/ package root | yes | yes | n/a | yes | yes | n/a |
agents/ folder OR all-in-one agents file | one file | yaml | one file | folder | one file | server |
Separate tools/ folder | yes (template) | yes | implicit | yes | implicit | server |
| Workflows/orchestration distinct from agents | graph.py | crew.py | manual | workflows/ | pydantic_graph | server |
| Shared state schema (typed) | TypedDict | inputs dict | message types | TS types | dataclass Deps | memory blocks |
.env / .env.example | yes | yes | yes | yes | yes | yes |
Config file at root (langgraph.json / mastra config / pyproject.toml) | yes | yes | manual | yes | yes | n/a |
| Tests folder | yes | yes | yes | yes | yes | n/a |
| Shared knowledge in dedicated dir | optional | knowledge/ | manual | implicit | manual | folders/blocks |
| Persistence via runtime store (DB/checkpointer), NOT files | yes | yes | yes | yes | yes | yes |
Universal split: by responsibility (agent vs tool vs workflow vs config), not by lifecycle state.
Universal storage rule: durable state (memory, identity, message history, archival) lives in a database, NOT in folders next to code.
DIVERGENT
Section titled “DIVERGENT”| Question | Answers |
|---|---|
| One agent file vs one agent folder? | Mastra: file-per-agent. CrewAI: all agents in one YAML. LangGraph: one node per agent (no file). AutoGen: all in one .py. PydanticAI: all in agent.py. |
| Declarative (YAML) or imperative (code)? | CrewAI: YAML+code split. PydanticAI: optional YAML. Mastra/LangGraph/AutoGen: code only. |
| Persona stored where? | Letta: .txt in personas/. CrewAI: YAML backstory. Everyone else: inline system_message string. |
| Multi-crew / nested teams? | CrewAI Flows: crews/<crew_name>/ subdir. AutoGen: distributed run_<agent>.py files. LangGraph: subgraphs. |
| Shared base for specialization? | AutoGen: inheritance (BaseGroupChatAgent). Others: composition + passing shared deps. |
Verdict on Wes’s Active/Reference/Logs/Archive Pattern
Section titled “Verdict on Wes’s Active/Reference/Logs/Archive Pattern”Does any framework recommend this? No.
Section titled “Does any framework recommend this? No.”I searched docs and 20+ example trees across 7 frameworks. None of them organize code by lifecycle state. They all organize by role/responsibility.
Why frameworks don’t do it
Section titled “Why frameworks don’t do it”The Active/Reference/Logs/Archive distinction is a runtime-state concern, and every framework pushes runtime state out of the code tree into a store:
| Wes’s dimension | Framework equivalent | Where it lives |
|---|---|---|
Active/ | running agent instances | runtime memory + checkpointer (Postgres/SQLite/LibSQL) |
Reference/ | knowledge sources | CrewAI knowledge/, Letta folders/blocks, vector stores |
Logs/ | message history, traces | DB tables (Letta recall memory, LangGraph checkpoints), observability tools |
Archive/ | inactive agents, old threads | soft-delete flags in DB, or vector-store TTL |
The convergent answer: state lives in databases, code is organized by what it IS.
What Wes’s pattern gets right
Section titled “What Wes’s pattern gets right”The instinct that every variant folder should follow the same layout is correct and matches every framework. Mastra is the strongest analog — every example has the same src/mastra/{agents,tools,workflows}/index.ts skeleton. Predictability of file location across variants is a real production virtue.
Where Wes’s pattern struggles
Section titled “Where Wes’s pattern struggles”Logs/next to code blurs immutable code with mutable state. Logs grow without bound. Mixing them into git is painful. Every framework treats logs as runtime output, not source.Archive/invites code rot. Mastra/CrewAI/LangGraph have no equivalent because deprecated agents get deleted (or feature-flagged in config), not moved. The vault is a better archive surface than the code tree.Active/vsReference/— what’s the difference for an agent’s persona doc? A persona file is BOTH active (loaded into context) AND reference (read-only). The split forces a false binary.
The better pattern (still consistent at every level)
Section titled “The better pattern (still consistent at every level)”Borrow from Mastra + Letta + CrewAI. Same skeleton everywhere, role-based, with runtime state pushed out:
<variant-or-project>/├── CLAUDE.md # persona / identity (the "Active" identity surface)├── agents/ # sub-agents, one file each├── tools/ # tool definitions├── workflows/ | flows/ # orchestration├── knowledge/ # immutable reference docs (what Wes calls "Reference")├── config/ # YAML or JSON declarative configs├── tests/├── .env.example└── README.mdThen outside the tree:
- State (the “Active” runtime): D1 / fleet-node KV / checkpointer
- Logs (the “Logs”):
~/.claude/projects/*.jsonl+ Cheesegrater central log + Cloudflare Worker telemetry - Archive (the “Archive”): vault
Fleet/working/for prior canon,git mvdeprecated agents into a top-levelarchived/only if you really need them on disk
If Wes insists on lifecycle dimension
Section titled “If Wes insists on lifecycle dimension”The least bad way to keep Active/Reference/Logs/Archive is to make it the top-level dimension with role-based subdirs underneath, NOT the other way around:
fleet-root/├── Active/│ ├── pepper/│ │ ├── agents/│ │ ├── tools/│ │ ├── workflows/│ │ └── CLAUDE.md│ └── nagatha/│ └── ... same skeleton├── Reference/ # shared docs, knowledge sources, persona templates├── Logs/ # symlink to runtime log dirs, NOT committed└── Archive/ # deprecated variants, full skeleton preservedThat gets you:
- Consistent inner skeleton (matches Mastra/CrewAI)
- Lifecycle dimension visible at the top
Logs/as a symlink avoids the git pollution problemArchive/as a freezer (whole variant moved, not files within a variant)
This is closest in spirit to AutoGen’s run_<agent>.py distributed pattern (whole launcher per agent) and Mastra’s per-variant src/mastra/ skeleton.
Recommendation Ranking
Section titled “Recommendation Ranking”- Best fit for Wes’s fleet: Mastra-style
agents/ tools/ workflows/ index.tsskeleton replicated per variant, with state/logs/archive handled by D1 + vault + symlinks. Reason: TS or not, Mastra’s pattern is the cleanest production analog of what Wes is doing (per-variant identity files, shared tool library, declarative wire-up). It’s also the most consistent across examples. - Strong alternative: CrewAI YAML-first pattern. Persona/role/goal/backstory in
agents.yaml, tools wired increw.py. Reason: Forces declarative persona separation from code. Maps perfectly to Wes’s idea of a variant-mapping doc as canon. - For memory/identity: Steal Letta’s memory-block + folder model. Shared blocks attachable to multiple agents = perfect for fleet-wide “company info,” “client info,” “active priorities.”
- For state scoping: Steal Mem0’s 4-level scoping (
user_id/agent_id/app_id/run_id). Maps to Wes’s machine / variant / project / session naturally. - Do not adopt: AutoGen’s distributed multi-process layout. It’s the closest structural match but the operational complexity is wrong for solo-operator scale.
Sources
Section titled “Sources”- LangGraph application structure: https://docs.langchain.com/oss/python/langgraph/application-structure
- LangGraph new project template: https://github.com/langchain-ai/new-langgraph-project
- LangGraph react-agent template: https://github.com/langchain-ai/react-agent
- LangGraph supervisor: https://github.com/langchain-ai/langgraph-supervisor-py
- CrewAI examples (crews + flows): https://github.com/crewAIInc/crewAI-examples
- CrewAI marketing_strategy: https://github.com/crewAIInc/crewAI-examples/tree/main/crews/marketing_strategy
- CrewAI email flow: https://github.com/crewAIInc/crewAI-examples/tree/main/flows/email_auto_responder_flow
- AutoGen distributed group chat: https://github.com/microsoft/autogen/tree/main/python/samples/core_distributed-group-chat
- Mastra project structure docs: https://mastra.ai/docs/getting-started/project-structure
- Mastra agent example: https://github.com/mastra-ai/mastra/tree/main/examples/agent
- Mastra durable-agents example: https://github.com/mastra-ai/mastra/tree/main/examples/durable-agents
- Pydantic AI medical delegation: https://github.com/pydantic/pydantic-ai/blob/main/examples/pydantic_ai_examples/medical_agent_delegation.py
- Pydantic AI slack lead qualifier: https://github.com/pydantic/pydantic-ai/tree/main/examples/pydantic_ai_examples/slack_lead_qualifier
- Pydantic AI agent spec (YAML): https://github.com/pydantic/pydantic-ai/blob/main/docs/agent-spec.md
- Letta personas: https://github.com/letta-ai/letta/tree/main/letta/personas/examples
- Letta memory blocks API: https://docs.letta.com (Memory Blocks API)
- Mem0 architecture: https://github.com/mem0ai/mem0/blob/main/skills/mem0/references/architecture.md
- Mem0 scoping patterns: https://github.com/mem0ai/mem0/blob/main/skills/mem0/references/architecture.md