Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 34 additions & 28 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,55 +47,61 @@ Here's a simple example to get you started:
```ruby
require 'mars'

# Define agents
class Agent1 < Mars::Agent
# Define a RubyLLM agent
class MyAgent < RubyLLM::Agent
model "gpt-4o"
instructions "You are a helpful assistant."
end

class Agent2 < Mars::Agent
# Wrap it in a MARS step
class MyStep < MARS::AgentStep
agent MyAgent
end

class Agent3 < Mars::Agent
end

# Create agents
agent1 = Agent1.new
agent2 = Agent2.new
agent3 = Agent3.new
# Create steps
step1 = MyStep.new(name: "step1")
step2 = MyStep.new(name: "step2")
step3 = MyStep.new(name: "step3")

# Create a sequential workflow
workflow = Mars::Workflows::Sequential.new(
workflow = MARS::Workflows::Sequential.new(
"My First Workflow",
steps: [agent1, agent2, agent3]
steps: [step1, step2, step3]
)

# Run the workflow
result = workflow.run("Your input here")
context = workflow.run("Your input here")
context.current_input # final output
context[:step1] # access any step's output by name
```

## Core Concepts

### Agents
### Agent Steps

Agents are the basic building blocks of MARS. They represent individual units of work:
Agent steps are the basic building blocks of MARS. They wrap a `RubyLLM::Agent` subclass for workflow orchestration:

```ruby
class CustomAgent < Mars::Agent
def system_prompt
"You are a helpful assistant"
end
class ResearcherAgent < RubyLLM::Agent
model "gpt-4o"
instructions "You research topics thoroughly."
tools WebSearch
schema OutputSchema
end

agent = CustomAgent.new(
options: { model: "gpt-4o" }
)
class ResearcherStep < MARS::AgentStep
agent ResearcherAgent
end

step = ResearcherStep.new(name: "researcher")
```

### Sequential Workflows

Execute agents one after another, passing outputs as inputs:

```ruby
sequential = Mars::Workflows::Sequential.new(
sequential = MARS::Workflows::Sequential.new(
"Sequential Pipeline",
steps: [agent1, agent2, agent3]
)
Expand All @@ -106,12 +112,12 @@ sequential = Mars::Workflows::Sequential.new(
Run multiple agents concurrently and aggregate their results:

```ruby
aggregator = Mars::Aggregator.new(
aggregator = MARS::Aggregator.new(
"Results Aggregator",
operation: lambda { |results| results.join(", ") }
)

parallel = Mars::Workflows::Parallel.new(
parallel = MARS::Workflows::Parallel.new(
"Parallel Pipeline",
steps: [agent1, agent2, agent3],
aggregator: aggregator
Expand All @@ -123,7 +129,7 @@ parallel = Mars::Workflows::Parallel.new(
Create conditional branching in your workflows:

```ruby
gate = Mars::Gate.new(
gate = MARS::Gate.new(
"Decision Gate",
condition: ->(input) { input[:score] > 0.5 ? :success : :failure },
branches: {
Expand All @@ -138,7 +144,7 @@ gate = Mars::Gate.new(
Generate Mermaid diagrams to visualize your workflows:

```ruby
diagram = Mars::Rendering::Mermaid.new(workflow).render
diagram = MARS::Rendering::Mermaid.new(workflow).render
File.write("workflow_diagram.md", diagram)
```

Expand Down Expand Up @@ -197,7 +203,7 @@ The gem is available as open source under the terms of the [MIT License](https:/

## Code of Conduct

Everyone interacting in the Mars project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/rootstrap/mars/blob/main/CODE_OF_CONDUCT.md).
Everyone interacting in the MARS project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/rootstrap/mars/blob/main/CODE_OF_CONDUCT.md).

## Credits

Expand Down
68 changes: 36 additions & 32 deletions examples/complex_llm_workflow/generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,48 +37,52 @@ def execute(latitude:, longitude:)
end
end

# Define LLMs
class Agent1 < MARS::Agent
def system_prompt
"You are a helpful assistant that can answer questions.
When asked about a country, only answer with its name."
end
# Define RubyLLM agents
class CountryAgent < RubyLLM::Agent
model "gpt-4o"
instructions "You are a helpful assistant that can answer questions. " \
"When asked about a country, only answer with its name."
end

class Agent2 < MARS::Agent
def system_prompt
"You are a helpful assistant that can answer questions and help with tasks.
Return information about the typical food of the country."
end
class FoodAgent < RubyLLM::Agent
model "gpt-4o"
instructions "You are a helpful assistant. Return information about the typical food of the country."
end

class Agent3 < MARS::Agent
def system_prompt
"You are a helpful assistant that can answer questions and help with tasks.
Return information about the popular sports of the country."
end
class SportsAgent < RubyLLM::Agent
model "gpt-4o"
instructions "You are a helpful assistant. Return information about the popular sports of the country."
schema SportsSchema
end

def schema
SportsSchema.new
end
class WeatherAgent < RubyLLM::Agent
model "gpt-4o"
instructions "You are a helpful assistant. Return the current weather of the country's capital."
tools Weather
end

class Agent4 < MARS::Agent
def system_prompt
"You are a helpful assistant that can answer questions and help with tasks.
Return the current weather of the country's capital."
end
# Define MARS steps wrapping RubyLLM agents
class CountryStep < MARS::AgentStep
agent CountryAgent
end

def tools
[Weather.new]
end
class FoodStep < MARS::AgentStep
agent FoodAgent
end

class SportsStep < MARS::AgentStep
agent SportsAgent
end

class WeatherStep < MARS::AgentStep
agent WeatherAgent
end

# Create the LLMs
llm1 = Agent1.new(options: { model: "gpt-4o" })
llm2 = Agent2.new(options: { model: "gpt-4o" })
llm3 = Agent3.new(options: { model: "gpt-4o" })
llm4 = Agent4.new(options: { model: "gpt-4o" })
# Create the steps
llm1 = CountryStep.new(name: "Country")
llm2 = FoodStep.new(name: "Food")
llm3 = SportsStep.new(name: "Sports")
llm4 = WeatherStep.new(name: "Weather")

parallel_workflow = MARS::Workflows::Parallel.new(
"Parallel workflow",
Expand Down
64 changes: 64 additions & 0 deletions examples/complex_workflow/diagram.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Main Pipeline</title>
<style>
body { font-family: system-ui, sans-serif; margin: 2rem; background: #fafafa; }
h1 { color: #333; }
#diagram { background: white; padding: 2rem; border-radius: 8px; box-shadow: 0 1px 3px rgba(0,0,0,0.1); }
</style>
</head>
<body>
<h1>Main Pipeline</h1>
<div id="diagram"></div>
<script type="module">
import { renderMermaidSVG } from "https://esm.sh/beautiful-mermaid@1";
const diagram = `flowchart LR
in((In))
out((Out))
agent1[agent1]
gate{Gate}
agent4[agent4]
parallel_workflow_aggregator[Parallel workflow Aggregator]
agent2[agent2]
agent3[agent3]
parallel_workflow_2_aggregator[Parallel workflow 2 Aggregator]
agent5[agent5]
subgraph main_pipeline["Main Pipeline"]
agent1
gate
parallel_workflow_aggregator
subgraph parallel_workflow_2["Parallel workflow 2"]
subgraph sequential_workflow["Sequential workflow"]
agent4
subgraph parallel_workflow["Parallel workflow"]
agent2
agent3
end
parallel_workflow_aggregator
end
agent5
end
parallel_workflow_2_aggregator
end
in --> agent1
agent1 --> gate
gate -->|warning| agent4
gate -->|error| agent2
gate -->|error| agent3
gate --> agent4
gate --> agent5
agent4 --> agent2
agent4 --> agent3
agent2 --> parallel_workflow_aggregator
parallel_workflow_aggregator --> parallel_workflow_2_aggregator
agent3 --> parallel_workflow_aggregator
parallel_workflow_2_aggregator --> out
agent5 --> parallel_workflow_2_aggregator`;
const svg = renderMermaidSVG(diagram);
document.getElementById("diagram").innerHTML = svg;
</script>
</body>
</html>
35 changes: 16 additions & 19 deletions examples/complex_workflow/diagram.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,29 @@
flowchart LR
in((In))
out((Out))
agent1[Agent1]
agent1[agent1]
gate{Gate}
agent4[Agent4]
agent4[agent4]
parallel_workflow_aggregator[Parallel workflow Aggregator]
agent2[Agent2]
agent3[Agent3]
agent2[agent2]
agent3[agent3]
parallel_workflow_2_aggregator[Parallel workflow 2 Aggregator]
agent5[Agent5]
subgraph parallel_workflow_2["Parallel workflow 2"]
sequential_workflow
agent5
end
subgraph parallel_workflow["Parallel workflow"]
agent2
agent3
end
subgraph sequential_workflow["Sequential workflow"]
agent4
parallel_workflow
parallel_workflow_aggregator
end
agent5[agent5]
subgraph main_pipeline["Main Pipeline"]
agent1
gate
parallel_workflow_aggregator
parallel_workflow_2
subgraph parallel_workflow_2["Parallel workflow 2"]
subgraph sequential_workflow["Sequential workflow"]
agent4
subgraph parallel_workflow["Parallel workflow"]
agent2
agent3
end
parallel_workflow_aggregator
end
agent5
end
parallel_workflow_2_aggregator
end
in --> agent1
Expand Down
10 changes: 5 additions & 5 deletions examples/complex_workflow/generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,19 @@
require_relative "../../lib/mars"

# Define LLMs
class Agent1 < MARS::Agent
class Agent1 < MARS::AgentStep
end

class Agent2 < MARS::Agent
class Agent2 < MARS::AgentStep
end

class Agent3 < MARS::Agent
class Agent3 < MARS::AgentStep
end

class Agent4 < MARS::Agent
class Agent4 < MARS::AgentStep
end

class Agent5 < MARS::Agent
class Agent5 < MARS::AgentStep
end

# Create the LLMs
Expand Down
6 changes: 3 additions & 3 deletions examples/parallel_workflow/generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@
require_relative "../../lib/mars"

# Define the LLMs
class Agent1 < MARS::Agent
class Agent1 < MARS::AgentStep
end

class Agent2 < MARS::Agent
class Agent2 < MARS::AgentStep
end

class Agent3 < MARS::Agent
class Agent3 < MARS::AgentStep
end

# Create the LLMs
Expand Down
6 changes: 3 additions & 3 deletions examples/simple_workflow/generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@
require_relative "../../lib/mars"

# Define the LLMs
class Agent1 < MARS::Agent
class Agent1 < MARS::AgentStep
end

class Agent2 < MARS::Agent
class Agent2 < MARS::AgentStep
end

class Agent3 < MARS::Agent
class Agent3 < MARS::AgentStep
end

# Create the LLMs
Expand Down
Loading