Excellent, this is a fantastic and timely request. Analyzing the architecture of jido
and foundation
reveals two powerful but overlapping systems. foundation
is a generic, robust infrastructure layer, while jido
is a feature-rich, high-level agent framework.
The key to a robust and scalable future is not to choose one over the other, but to refactor them into a clean, layered architecture. jido
should be built on top of foundation
, leveraging its infrastructure primitives. This creates a powerful separation of concerns, making foundation
a reusable “BEAM OS” and jido
the “Agent Runtime” that runs on it.
This proposal will:
- Analyze the Feasibility of integrating
jido
andfoundation
. - Propose a Robust Architecture that refactors them into coherent layers.
- Provide a Concrete Integration Plan with code-level examples.
- Illustrate the End State showing how
ElixirML
would use this new architecture.
Part 1: Feasibility Analysis
A direct merge is infeasible and undesirable. Both codebases have developed parallel solutions for similar problems (e.g., process management, telemetry). Simply combining them would create a monolithic, confusing system.
foundation
Strengths:
- Generic Primitives:
ProcessRegistry
,ServiceRegistry
,CircuitBreaker
,RateLimiter
are domain-agnostic and highly reusable. - Infrastructure-focused: Excellent at managing core BEAM concerns like processes, configuration, and events.
- Distribution-Ready Concepts: The MABEAM modules in
foundation
introduce coordination protocols (Auction
,Market
) that are fundamental to multi-agent systems.
jido
Strengths:
- High-Level Agent Model: Provides a complete, user-friendly framework (
Agent
,Action
,Skill
,Sensor
) for building agents. - Rich Feature Set: Comes with pre-built actions, a workflow engine, and tools for easy agent development.
- Clear Abstractions: The concepts of
Instruction
,Runner
, andDirective
provide a clear model for agent execution.
The Core Conflict: jido
has its own implicit infrastructure (e.g., its own agent supervision and lifecycle management). foundation
has started to include agent-specific application logic (mabeam
). This creates a blurry line and duplicates effort.
Conclusion: It is not only feasible but architecturally necessary to integrate these two. The correct approach is to refactor jido
to be a consumer of foundation
’s services, making foundation
the explicit infrastructure layer for jido
.
Part 2: Proposed Robust Architecture: A Layered Approach
The ideal architecture organizes the system into three distinct layers, each with a clear responsibility:
(Moved from foundation/mabeam)"] end subgraph "Layer 1: Foundation - The BEAM OS" F_Infra["\`Foundation.Infrastructure\`
(Circuit Breaker, Rate Limiter)"] F_Registry["\`Foundation.ProcessRegistry\` & \`ServiceRegistry\`"] F_Events["\`Foundation.Events\` & \`Telemetry\`"] F_Config["\`Foundation.Config\`"] F_Coord["\`Foundation.Coordination.Primitives\`
(Consensus, Barrier Sync)"] end L3A --> L2A; L3B --> L2B; L3C --> L2B; L2A --> F_Registry; L2B --> F_Infra; L2D --> F_Coord; L2A --> F_Events;
Layer 1: foundation
- The Generic BEAM Toolkit
- Responsibility: Provide robust, reusable, domain-agnostic infrastructure for any Elixir application.
- Key Modules:
ProcessRegistry
,ServiceRegistry
,EventStore
,TelemetryService
,CircuitBreaker
,RateLimiter
. - Change: The high-level economic protocols (
Auction
,Market
) insidefoundation/mabeam
should be moved out offoundation
and intojido
. The low-levelCoordination.Primitives
(consensus, barriers) correctly belong infoundation
.
Layer 2: jido
- The Universal Agent Framework (MABEAM)
- Responsibility: Provide the complete runtime and set of abstractions for building, running, and coordinating autonomous agents.
jido
is the MABEAM framework. - Key Modules:
Jido.Agent
,Jido.Action
,Jido.Skill
,Jido.Sensor
. - Change:
jido
will be refactored to usefoundation
’s services for its infrastructure needs.
Layer 3: ElixirML
- The Domain-Specific Application
- Responsibility: Define concrete agents, actions, and skills that solve ML-specific problems.
- Implementation:
ElixirML
modules willuse Jido.Agent
oruse Jido.Action
to implement the application logic, leveraging thejido
framework.
Part 3: Concrete Integration & Refactoring Plan
This plan details how to refactor jido
to be built on foundation
.
Step 1: Replace jido
’s Implicit Infrastructure with foundation
Process Management:
- The
Jido.Agent.Server.start_link
function will be modified. Instead of managing its own name registration, it will useFoundation.ServiceRegistry
. - Code Example (
jido/agent/server.ex
):# In Jido.Agent.Server def start_link(opts) do # ... build agent, validate opts ... agent_id = Keyword.get(opts, :id) registry = Keyword.get(opts, :registry, Foundation.ProcessRegistry) namespace = Keyword.get(opts, :namespace, :production) # Use Foundation's registry for naming and discovery via_tuple = Foundation.ServiceRegistry.via_tuple(namespace, agent_id) GenServer.start_link(__MODULE__, opts, name: via_tuple) end
- The
Observability & Logging:
Jido.Telemetry
should be removed. Instead,Jido.Exec
andJido.Agent.Server
will emit telemetry events usingFoundation.Telemetry.execute/3
.Jido.Actions.Basic.Log
will be refactored to call theFoundation
logger, which is already configured for structured logging.- Code Example (
jido/exec.ex
):# In Jido.Exec private functions defp start_span(action, params, context, telemetry) do # ... # Use Foundation's Telemetry Foundation.Telemetry.execute([:jido, :action, :start], %{}, metadata) end
State & Configuration:
- The
Jido.Agent.Server
will remain responsible for its own instance state (ServerState
). - For configuration shared across multiple agents or the system,
jido
’s components should read fromFoundation.Config.get/1
.
- The
Step 2: Relocate and Refine MABEAM Coordination Logic
Move
Auction
andMarket
fromfoundation
tojido
:- Move the files from
foundation/mabeam/coordination/
to a newjido/coordination/
directory. - Refactor them to be regular modules or GenServers, not tied to
foundation
’s internal structure. They are now part of thejido
agent framework’s offerings.
- Move the files from
Integrate Coordination into
jido
Actions:- The
jido
framework can now offer specialized actions that trigger these coordination protocols. - Code Example (new file
jido/actions/coordination.ex
):defmodule Jido.Actions.Coordination do alias Jido.Coordination.{Auction, Consensus} alias Jido.Action defmodule RunAuction do use Action, name: "run_auction", description: "Initiate a resource auction" # schema for auction_spec, participants, etc. def run(params, _context) do # The jido action now calls the coordination protocol Auction.run_auction(params.auction_spec, params.participants) end end defmodule SeekConsensus do use Action, name: "seek_consensus", description: "Initiate consensus among agents" # schema for proposal, agents, etc. def run(params, _context) do Consensus.run(params.proposal, params.agents) end end end
- The
Step 3: Clarify the Agent Model
- A
Jido.Agent
is a behavior that defines the logic and state for an autonomous process. - A
Jido.Agent.Server
is the GenServer that hosts and executes aJido.Agent
. It handles the OTP-level concerns (message queue, state loop). - The
Jido.Runner
(e.g.,Simple
,Chain
) is the “CPU” of the agent, executingInstruction
s from the queue. This architecture is sound and should be retained.
Part 4: The Final Integrated ElixirML
Application
With this refactored architecture, building an ElixirML
agent becomes clean and intuitive.
1. Define an ElixirML
Agent:
The ElixirML
developer focuses purely on the agent’s logic, using jido
’s high-level abstractions.
# In elixir_ml/agents/coder_agent.ex
defmodule ElixirML.Agents.CoderAgent do
use Jido.Agent,
name: "coder_agent",
description: "An agent that writes code based on specifications.",
# The agent has its own state schema, independent of the infrastructure
schema: [
current_task: [type: :string],
language_proficiency: [type: :map, default: %{elixir: 0.9, python: 0.8}]
]
# Agent can define its own startup logic
@impl Jido.Agent
def mount(state, _opts) do
# Log using foundation, via jido
Jido.Actions.Basic.Log.run(%{level: :info, message: "CoderAgent mounting."}, %{})
{:ok, state}
end
end
2. Define an ElixirML
Action:
The developer writes a pure function that performs a task. It can use foundation
’s infrastructure for resilience.
# In elixir_ml/actions/generate_code_action.ex
defmodule ElixirML.Actions.GenerateCodeAction do
use Jido.Action, name: "generate_code"
alias Foundation.Infrastructure.CircuitBreaker
# Action to call an external LLM API to generate code
def run(params, _context) do
# Use Foundation's circuit breaker to protect the external call
CircuitBreaker.execute(:llm_api, fn ->
# call external LLM service...
{:ok, %{generated_code: "def hello, do: :world"}}
end)
end
end
3. Orchestrate Agents:
An orchestrator agent in ElixirML
can now plan and execute work for other agents using jido
’s directive system.
# In elixir_ml/agents/project_manager_agent.ex
defmodule ElixirML.Agents.ProjectManagerAgent do
use Jido.Agent, name: "project_manager"
alias Jido.Actions.Directives
# This agent's job is to delegate tasks to other agents
def plan_and_delegate(task_spec) do
# Plan a sequence of actions for the CoderAgent
instructions_for_coder = [
# An ElixirML-specific action
{ElixirML.Actions.GenerateCodeAction, %{spec: task_spec}},
# A built-in Jido action
{Jido.Actions.Files.WriteFile, %{path: "lib/new_feature.ex", content: ...}}
]
# Use a Jido Directive to enqueue these instructions on the CoderAgent
directive = %Directives.EnqueueAction{
action: ElixirML.Agents.CoderAgent, # Target agent
params: %{instructions: instructions_for_coder}
}
# Return the directive to the Jido runtime
{:ok, %{}, directive}
end
end
Conclusion and Recommendation
The path forward is clear: Refactor, Don’t Replace.
- Purify
foundation
: Make it the universal, domain-agnostic BEAM OS. Movemabeam
coordination protocols out. - Elevate
jido
: Position it as the standard agent framework (MABEAM
) built onfoundation
. It provides the agent runtime, abstractions, and now the coordination protocols. - Empower
ElixirML
: Allow it to focus on defining ML agents and actions, leveraging the powerful, layered architecture underneath.
This approach creates a robust, maintainable, and highly reusable system. It leverages the strengths of both existing codebases, resolves their architectural conflicts, and provides a clear and powerful model for building sophisticated, multi-agent systems in Elixir.