rcrewai-rails 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +222 -0
  4. data/Rakefile +6 -0
  5. data/app/controllers/rcrewai/rails/application_controller.rb +17 -0
  6. data/app/controllers/rcrewai/rails/crews_controller.rb +67 -0
  7. data/app/controllers/rcrewai/rails/executions_controller.rb +65 -0
  8. data/app/jobs/rcrewai/rails/crew_execution_job.rb +82 -0
  9. data/app/jobs/rcrewai/rails/task_execution_job.rb +63 -0
  10. data/app/models/rcrewai/rails/agent.rb +58 -0
  11. data/app/models/rcrewai/rails/application_record.rb +8 -0
  12. data/app/models/rcrewai/rails/crew.rb +65 -0
  13. data/app/models/rcrewai/rails/execution.rb +98 -0
  14. data/app/models/rcrewai/rails/execution_log.rb +18 -0
  15. data/app/models/rcrewai/rails/task.rb +69 -0
  16. data/app/models/rcrewai/rails/task_assignment.rb +12 -0
  17. data/app/models/rcrewai/rails/task_dependency.rb +42 -0
  18. data/app/views/layouts/rcrewai/rails/application.html.erb +37 -0
  19. data/app/views/rcrewai/rails/crews/index.html.erb +42 -0
  20. data/app/views/rcrewai/rails/crews/show.html.erb +95 -0
  21. data/app/views/rcrewai/rails/executions/show.html.erb +92 -0
  22. data/config/routes.rb +50 -0
  23. data/lib/generators/rcrew_a_i/rails/crew/crew_generator.rb +42 -0
  24. data/lib/generators/rcrew_a_i/rails/crew/templates/agent.rb.erb +45 -0
  25. data/lib/generators/rcrew_a_i/rails/crew/templates/crew.rb.erb +72 -0
  26. data/lib/generators/rcrew_a_i/rails/install/install_generator.rb +40 -0
  27. data/lib/generators/rcrew_a_i/rails/install/templates/create_rcrewai_tables.rb +113 -0
  28. data/lib/generators/rcrew_a_i/rails/install/templates/rcrewai.rb +53 -0
  29. data/lib/generators/rcrewai/rails/crew/crew_generator.rb +42 -0
  30. data/lib/generators/rcrewai/rails/crew/templates/agent.rb.erb +45 -0
  31. data/lib/generators/rcrewai/rails/crew/templates/crew.rb.erb +72 -0
  32. data/lib/generators/rcrewai/rails/install/install_generator.rb +40 -0
  33. data/lib/generators/rcrewai/rails/install/templates/create_rcrewai_tables.rb +113 -0
  34. data/lib/generators/rcrewai/rails/install/templates/rcrewai.rb +53 -0
  35. data/lib/rcrewai/rails/agent_builder.rb +123 -0
  36. data/lib/rcrewai/rails/configuration.rb +22 -0
  37. data/lib/rcrewai/rails/crew_builder.rb +112 -0
  38. data/lib/rcrewai/rails/engine.rb +38 -0
  39. data/lib/rcrewai/rails/tools/action_mailer_tool.rb +60 -0
  40. data/lib/rcrewai/rails/tools/active_record_tool.rb +67 -0
  41. data/lib/rcrewai/rails/tools/active_storage_tool.rb +122 -0
  42. data/lib/rcrewai/rails/tools/rails_cache_tool.rb +69 -0
  43. data/lib/rcrewai/rails/tools/rails_logger_tool.rb +57 -0
  44. data/lib/rcrewai/rails/version.rb +5 -0
  45. data/lib/rcrewai/rails.rb +31 -0
  46. data/lib/rcrewai-rails.rb +1 -0
  47. data/rcrewai-rails.gemspec +48 -0
  48. metadata +261 -0
@@ -0,0 +1,98 @@
1
+ module RcrewAI
2
+ module Rails
3
+ class Execution < ApplicationRecord
4
+ self.table_name = "rcrewai_executions"
5
+
6
+ belongs_to :crew
7
+ has_many :execution_logs, dependent: :destroy
8
+
9
+ validates :status, inclusion: { in: %w[pending running completed failed cancelled] }
10
+
11
+ serialize :inputs, coder: JSON
12
+ serialize :output, coder: JSON
13
+ serialize :error_details, coder: JSON
14
+
15
+ scope :successful, -> { where(status: "completed") }
16
+ scope :failed, -> { where(status: "failed") }
17
+ scope :pending, -> { where(status: "pending") }
18
+ scope :running, -> { where(status: "running") }
19
+ scope :recent, -> { order(created_at: :desc) }
20
+
21
+ before_create :set_initial_status
22
+
23
+ def start!
24
+ update!(
25
+ status: "running",
26
+ started_at: Time.current
27
+ )
28
+ end
29
+
30
+ def complete!(result)
31
+ update!(
32
+ status: "completed",
33
+ output: result,
34
+ completed_at: Time.current,
35
+ duration_seconds: calculate_duration
36
+ )
37
+ end
38
+
39
+ def fail!(error)
40
+ update!(
41
+ status: "failed",
42
+ error_message: error.message,
43
+ error_details: {
44
+ class: error.class.name,
45
+ message: error.message,
46
+ backtrace: error.backtrace&.first(10)
47
+ },
48
+ completed_at: Time.current,
49
+ duration_seconds: calculate_duration
50
+ )
51
+ end
52
+
53
+ def cancel!
54
+ update!(
55
+ status: "cancelled",
56
+ completed_at: Time.current,
57
+ duration_seconds: calculate_duration
58
+ )
59
+ end
60
+
61
+ def running?
62
+ status == "running"
63
+ end
64
+
65
+ def completed?
66
+ status == "completed"
67
+ end
68
+
69
+ def failed?
70
+ status == "failed"
71
+ end
72
+
73
+ def finished?
74
+ %w[completed failed cancelled].include?(status)
75
+ end
76
+
77
+ def log(level, message, details = {})
78
+ execution_logs.create!(
79
+ level: level,
80
+ message: message,
81
+ details: details,
82
+ timestamp: Time.current
83
+ )
84
+ end
85
+
86
+ private
87
+
88
+ def set_initial_status
89
+ self.status ||= "pending"
90
+ end
91
+
92
+ def calculate_duration
93
+ return nil unless started_at.present?
94
+ (Time.current - started_at).to_i
95
+ end
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,18 @@
1
+ module RcrewAI
2
+ module Rails
3
+ class ExecutionLog < ApplicationRecord
4
+ self.table_name = "rcrewai_execution_logs"
5
+
6
+ belongs_to :execution
7
+
8
+ validates :level, inclusion: { in: %w[debug info warn error] }
9
+ validates :message, presence: true
10
+
11
+ serialize :details, coder: JSON
12
+
13
+ scope :errors, -> { where(level: "error") }
14
+ scope :warnings, -> { where(level: "warn") }
15
+ scope :recent, -> { order(timestamp: :desc) }
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,69 @@
1
+ module RcrewAI
2
+ module Rails
3
+ class Task < ApplicationRecord
4
+ self.table_name = "rcrewai_tasks"
5
+
6
+ belongs_to :crew
7
+ has_many :task_assignments, dependent: :destroy
8
+ has_many :agents, through: :task_assignments
9
+ has_many :task_dependencies, foreign_key: :task_id, dependent: :destroy
10
+ has_many :dependencies, through: :task_dependencies, source: :dependency
11
+
12
+ validates :description, presence: true
13
+ validates :expected_output, presence: true
14
+
15
+ serialize :context, coder: JSON, type: Array
16
+ serialize :output_json, coder: JSON
17
+ serialize :output_pydantic, coder: JSON
18
+ serialize :tools, coder: JSON, type: Array
19
+
20
+ scope :ordered, -> { order(position: :asc) }
21
+
22
+ def to_rcrew_task
23
+ RCrewAI::Task.new(
24
+ description: description,
25
+ expected_output: expected_output,
26
+ agent: agent&.to_rcrew_agent,
27
+ context: context,
28
+ async_execution: async_execution,
29
+ output_json: output_json,
30
+ output_pydantic: output_pydantic,
31
+ output_file: output_file,
32
+ tools: instantiated_tools,
33
+ callback: callback_method
34
+ )
35
+ end
36
+
37
+ def agent
38
+ agents.first
39
+ end
40
+
41
+ def instantiated_tools
42
+ return [] if tools.blank?
43
+
44
+ tools.map do |tool_config|
45
+ tool_class = tool_config["class"].constantize
46
+ tool_params = tool_config["params"] || {}
47
+ tool_class.new(**tool_params.symbolize_keys)
48
+ end
49
+ end
50
+
51
+ def add_dependency(other_task)
52
+ task_dependencies.create!(dependency: other_task)
53
+ end
54
+
55
+ def remove_dependency(other_task)
56
+ task_dependencies.where(dependency: other_task).destroy_all
57
+ end
58
+
59
+ private
60
+
61
+ def callback_method
62
+ return nil unless callback_class.present? && callback_method_name.present?
63
+
64
+ klass = callback_class.constantize
65
+ ->(output) { klass.new.send(callback_method_name, output) }
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,12 @@
1
+ module RcrewAI
2
+ module Rails
3
+ class TaskAssignment < ApplicationRecord
4
+ self.table_name = "rcrewai_task_assignments"
5
+
6
+ belongs_to :task
7
+ belongs_to :agent
8
+
9
+ validates :task_id, uniqueness: { scope: :agent_id }
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,42 @@
1
+ module RcrewAI
2
+ module Rails
3
+ class TaskDependency < ApplicationRecord
4
+ self.table_name = "rcrewai_task_dependencies"
5
+
6
+ belongs_to :task
7
+ belongs_to :dependency, class_name: "Task"
8
+
9
+ validates :task_id, uniqueness: { scope: :dependency_id }
10
+ validate :no_circular_dependencies
11
+
12
+ private
13
+
14
+ def no_circular_dependencies
15
+ return unless dependency
16
+
17
+ if creates_circular_dependency?
18
+ errors.add(:dependency, "would create a circular dependency")
19
+ end
20
+ end
21
+
22
+ def creates_circular_dependency?
23
+ visited = Set.new
24
+ queue = [dependency_id]
25
+
26
+ while queue.any?
27
+ current_id = queue.shift
28
+ return true if current_id == task_id
29
+
30
+ next if visited.include?(current_id)
31
+ visited.add(current_id)
32
+
33
+ TaskDependency.where(task_id: current_id).pluck(:dependency_id).each do |dep_id|
34
+ queue << dep_id
35
+ end
36
+ end
37
+
38
+ false
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,37 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>RcrewAI Rails</title>
5
+ <meta name="viewport" content="width=device-width,initial-scale=1">
6
+ <%= csrf_meta_tags %>
7
+ <%= csp_meta_tag %>
8
+
9
+ <%= stylesheet_link_tag "application", "data-turbo-track": "reload" %>
10
+ <%= javascript_include_tag "application", "data-turbo-track": "reload", defer: true %>
11
+ </head>
12
+
13
+ <body>
14
+ <nav class="navbar">
15
+ <div class="container">
16
+ <%= link_to "RcrewAI", root_path, class: "navbar-brand" %>
17
+ <div class="navbar-menu">
18
+ <%= link_to "Crews", crews_path, class: "navbar-item" %>
19
+ <%= link_to "Executions", executions_path, class: "navbar-item" %>
20
+ <%= link_to "Agents", agents_path, class: "navbar-item" %>
21
+ <%= link_to "Tasks", tasks_path, class: "navbar-item" %>
22
+ </div>
23
+ </div>
24
+ </nav>
25
+
26
+ <main class="container">
27
+ <% if notice.present? %>
28
+ <div class="notice"><%= notice %></div>
29
+ <% end %>
30
+ <% if alert.present? %>
31
+ <div class="alert"><%= alert %></div>
32
+ <% end %>
33
+
34
+ <%= yield %>
35
+ </main>
36
+ </body>
37
+ </html>
@@ -0,0 +1,42 @@
1
+ <div class="page-header">
2
+ <h1>Crews</h1>
3
+ <%= link_to "New Crew", new_crew_path, class: "btn btn-primary" %>
4
+ </div>
5
+
6
+ <div class="crews-grid">
7
+ <% @crews.each do |crew| %>
8
+ <div class="crew-card">
9
+ <h3><%= link_to crew.name, crew %></h3>
10
+ <p class="crew-description"><%= crew.description %></p>
11
+
12
+ <div class="crew-meta">
13
+ <span class="badge"><%= crew.process_type %></span>
14
+ <span class="badge"><%= crew.agents.count %> agents</span>
15
+ <span class="badge"><%= crew.tasks.count %> tasks</span>
16
+ </div>
17
+
18
+ <div class="crew-stats">
19
+ <% stats = crew.execution_stats %>
20
+ <div class="stat">
21
+ <strong>Total Runs:</strong> <%= stats[:total] %>
22
+ </div>
23
+ <div class="stat">
24
+ <strong>Success Rate:</strong>
25
+ <%= stats[:total] > 0 ? "#{(stats[:successful].to_f / stats[:total] * 100).round}%" : "N/A" %>
26
+ </div>
27
+ <div class="stat">
28
+ <strong>Avg Duration:</strong>
29
+ <%= stats[:average_duration] ? "#{stats[:average_duration].round}s" : "N/A" %>
30
+ </div>
31
+ </div>
32
+
33
+ <div class="crew-actions">
34
+ <%= link_to "View", crew, class: "btn btn-sm" %>
35
+ <%= link_to "Edit", edit_crew_path(crew), class: "btn btn-sm" %>
36
+ <%= button_to "Execute", execute_crew_path(crew), method: :post, class: "btn btn-sm btn-success" %>
37
+ </div>
38
+ </div>
39
+ <% end %>
40
+ </div>
41
+
42
+ <%= paginate @crews %>
@@ -0,0 +1,95 @@
1
+ <div class="page-header">
2
+ <h1><%= @crew.name %></h1>
3
+ <div class="actions">
4
+ <%= link_to "Edit", edit_crew_path(@crew), class: "btn" %>
5
+ <%= button_to "Execute", execute_crew_path(@crew), method: :post, class: "btn btn-success" %>
6
+ <%= button_to "Delete", @crew, method: :delete, data: { confirm: "Are you sure?" }, class: "btn btn-danger" %>
7
+ </div>
8
+ </div>
9
+
10
+ <div class="crew-details">
11
+ <p><%= @crew.description %></p>
12
+
13
+ <div class="metadata">
14
+ <div class="meta-item">
15
+ <strong>Process Type:</strong> <%= @crew.process_type %>
16
+ </div>
17
+ <div class="meta-item">
18
+ <strong>Memory:</strong> <%= @crew.memory_enabled ? "Enabled" : "Disabled" %>
19
+ </div>
20
+ <div class="meta-item">
21
+ <strong>Cache:</strong> <%= @crew.cache_enabled ? "Enabled" : "Disabled" %>
22
+ </div>
23
+ <div class="meta-item">
24
+ <strong>Status:</strong> <%= @crew.active ? "Active" : "Inactive" %>
25
+ </div>
26
+ </div>
27
+ </div>
28
+
29
+ <div class="section">
30
+ <h2>Agents (<%= @agents.count %>)</h2>
31
+ <div class="agents-list">
32
+ <% @agents.each do |agent| %>
33
+ <div class="agent-item">
34
+ <h4><%= agent.name %></h4>
35
+ <p><strong>Role:</strong> <%= agent.role %></p>
36
+ <p><strong>Goal:</strong> <%= agent.goal %></p>
37
+ <% if agent.tools.present? %>
38
+ <p><strong>Tools:</strong> <%= agent.tools.count %> configured</p>
39
+ <% end %>
40
+ </div>
41
+ <% end %>
42
+ </div>
43
+ </div>
44
+
45
+ <div class="section">
46
+ <h2>Tasks (<%= @tasks.count %>)</h2>
47
+ <div class="tasks-list">
48
+ <% @tasks.each do |task| %>
49
+ <div class="task-item">
50
+ <h4>Task #<%= task.position || task.id %></h4>
51
+ <p><%= task.description %></p>
52
+ <p><strong>Expected Output:</strong> <%= task.expected_output %></p>
53
+ <% if task.agents.any? %>
54
+ <p><strong>Assigned to:</strong> <%= task.agents.map(&:name).join(", ") %></p>
55
+ <% end %>
56
+ </div>
57
+ <% end %>
58
+ </div>
59
+ </div>
60
+
61
+ <div class="section">
62
+ <h2>Recent Executions</h2>
63
+ <% if @recent_executions.any? %>
64
+ <table class="table">
65
+ <thead>
66
+ <tr>
67
+ <th>ID</th>
68
+ <th>Status</th>
69
+ <th>Started</th>
70
+ <th>Duration</th>
71
+ <th>Actions</th>
72
+ </tr>
73
+ </thead>
74
+ <tbody>
75
+ <% @recent_executions.each do |execution| %>
76
+ <tr>
77
+ <td><%= link_to "##{execution.id}", execution %></td>
78
+ <td>
79
+ <span class="badge badge-<%= execution.status %>">
80
+ <%= execution.status %>
81
+ </span>
82
+ </td>
83
+ <td><%= execution.started_at&.strftime("%Y-%m-%d %H:%M") %></td>
84
+ <td><%= execution.duration_seconds ? "#{execution.duration_seconds}s" : "-" %></td>
85
+ <td>
86
+ <%= link_to "View", execution, class: "btn btn-sm" %>
87
+ </td>
88
+ </tr>
89
+ <% end %>
90
+ </tbody>
91
+ </table>
92
+ <% else %>
93
+ <p>No executions yet.</p>
94
+ <% end %>
95
+ </div>
@@ -0,0 +1,92 @@
1
+ <div class="page-header">
2
+ <h1>Execution #<%= @execution.id %></h1>
3
+ <div class="actions">
4
+ <% if @execution.running? %>
5
+ <%= button_to "Cancel", cancel_execution_path(@execution), method: :post, class: "btn btn-danger" %>
6
+ <% end %>
7
+ <%= link_to "Back to Crew", @execution.crew, class: "btn" %>
8
+ </div>
9
+ </div>
10
+
11
+ <div class="execution-details">
12
+ <div class="status-banner status-<%= @execution.status %>">
13
+ <strong>Status:</strong> <%= @execution.status.humanize %>
14
+ </div>
15
+
16
+ <div class="metadata-grid">
17
+ <div class="meta-item">
18
+ <strong>Crew:</strong> <%= link_to @execution.crew.name, @execution.crew %>
19
+ </div>
20
+ <div class="meta-item">
21
+ <strong>Started:</strong> <%= @execution.started_at&.strftime("%Y-%m-%d %H:%M:%S") || "Not started" %>
22
+ </div>
23
+ <div class="meta-item">
24
+ <strong>Completed:</strong> <%= @execution.completed_at&.strftime("%Y-%m-%d %H:%M:%S") || "In progress" %>
25
+ </div>
26
+ <div class="meta-item">
27
+ <strong>Duration:</strong> <%= @execution.duration_seconds ? "#{@execution.duration_seconds} seconds" : "N/A" %>
28
+ </div>
29
+ </div>
30
+
31
+ <% if @execution.inputs.present? %>
32
+ <div class="section">
33
+ <h3>Inputs</h3>
34
+ <pre class="code-block"><%= JSON.pretty_generate(@execution.inputs) %></pre>
35
+ </div>
36
+ <% end %>
37
+
38
+ <% if @execution.output.present? %>
39
+ <div class="section">
40
+ <h3>Output</h3>
41
+ <pre class="code-block"><%= JSON.pretty_generate(@execution.output) %></pre>
42
+ </div>
43
+ <% end %>
44
+
45
+ <% if @execution.error_message.present? %>
46
+ <div class="section error-section">
47
+ <h3>Error</h3>
48
+ <p class="error-message"><%= @execution.error_message %></p>
49
+ <% if @execution.error_details.present? %>
50
+ <details>
51
+ <summary>Error Details</summary>
52
+ <pre class="code-block"><%= JSON.pretty_generate(@execution.error_details) %></pre>
53
+ </details>
54
+ <% end %>
55
+ </div>
56
+ <% end %>
57
+ </div>
58
+
59
+ <div class="section">
60
+ <h2>Execution Logs</h2>
61
+
62
+ <div class="log-filters">
63
+ <%= link_to "All", execution_logs_path(@execution), class: "filter-btn", data: { turbo_frame: "logs" } %>
64
+ <%= link_to "Errors", execution_logs_path(@execution, level: "error"), class: "filter-btn", data: { turbo_frame: "logs" } %>
65
+ <%= link_to "Warnings", execution_logs_path(@execution, level: "warn"), class: "filter-btn", data: { turbo_frame: "logs" } %>
66
+ <%= link_to "Info", execution_logs_path(@execution, level: "info"), class: "filter-btn", data: { turbo_frame: "logs" } %>
67
+ </div>
68
+
69
+ <%= turbo_frame_tag "logs", data: { turbo_action: "advance" } do %>
70
+ <div class="logs-container">
71
+ <% @logs.each do |log| %>
72
+ <div class="log-entry log-<%= log.level %>">
73
+ <span class="log-timestamp"><%= log.timestamp.strftime("%H:%M:%S.%L") %></span>
74
+ <span class="log-level"><%= log.level.upcase %></span>
75
+ <span class="log-message"><%= log.message %></span>
76
+ <% if log.details.present? %>
77
+ <details class="log-details">
78
+ <summary>Details</summary>
79
+ <pre><%= JSON.pretty_generate(log.details) %></pre>
80
+ </details>
81
+ <% end %>
82
+ </div>
83
+ <% end %>
84
+ </div>
85
+
86
+ <%= paginate @logs %>
87
+ <% end %>
88
+ </div>
89
+
90
+ <% if @execution.running? %>
91
+ <%= turbo_stream_from @execution, :logs %>
92
+ <% end %>
data/config/routes.rb ADDED
@@ -0,0 +1,50 @@
1
+ RcrewAI::Rails::Engine.routes.draw do
2
+ root to: "crews#index"
3
+
4
+ resources :crews do
5
+ member do
6
+ post :execute
7
+ end
8
+ resources :agents
9
+ resources :tasks
10
+ end
11
+
12
+ resources :executions, only: [:index, :show] do
13
+ member do
14
+ post :cancel
15
+ get :logs
16
+ end
17
+ end
18
+
19
+ resources :agents do
20
+ resources :tools
21
+ end
22
+
23
+ resources :tasks do
24
+ member do
25
+ post :add_dependency
26
+ delete :remove_dependency
27
+ end
28
+ end
29
+
30
+ # API endpoints
31
+ namespace :api do
32
+ namespace :v1 do
33
+ resources :crews, only: [:index, :show, :create] do
34
+ member do
35
+ post :execute
36
+ end
37
+ end
38
+
39
+ resources :executions, only: [:index, :show] do
40
+ member do
41
+ get :status
42
+ get :logs
43
+ end
44
+ end
45
+ end
46
+ end
47
+
48
+ # Mount Turbo Streams for real-time updates
49
+ mount ActionCable.server => '/cable' if defined?(ActionCable)
50
+ end
@@ -0,0 +1,42 @@
1
+ require "rails/generators"
2
+
3
+ module RcrewAI
4
+ module Rails
5
+ module Generators
6
+ class CrewGenerator < ::Rails::Generators::NamedBase
7
+ source_root File.expand_path("templates", __dir__)
8
+
9
+ argument :process_type, type: :string, default: "sequential", banner: "sequential|hierarchical"
10
+
11
+ class_option :agents, type: :array, default: [], desc: "List of agents to create"
12
+ class_option :description, type: :string, desc: "Crew description"
13
+
14
+ def create_crew_file
15
+ template "crew.rb.erb", "app/crews/#{file_name}_crew.rb"
16
+ end
17
+
18
+ def create_agent_files
19
+ options[:agents].each do |agent_name|
20
+ @agent_name = agent_name
21
+ template "agent.rb.erb", "app/crews/agents/#{agent_name.underscore}_agent.rb"
22
+ end
23
+ end
24
+
25
+ def display_next_steps
26
+ say "\n✅ Created #{class_name}Crew!", :green
27
+ say "\nNext steps:", :yellow
28
+ say " 1. Configure your crew in app/crews/#{file_name}_crew.rb"
29
+ say " 2. Define tasks for your crew"
30
+ say " 3. Run your crew with: #{class_name}Crew.new.execute"
31
+ say "\n"
32
+ end
33
+
34
+ private
35
+
36
+ def crew_description
37
+ options[:description] || "#{class_name} crew for AI task orchestration"
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,45 @@
1
+ class <%= @agent_name.camelize %>Agent
2
+ include RcrewAI::Rails::AgentBuilder
3
+
4
+ def initialize
5
+ @agent = RcrewAI::Agent.new(
6
+ role: role,
7
+ goal: goal,
8
+ backstory: backstory,
9
+ memory: true,
10
+ verbose: true,
11
+ allow_delegation: false,
12
+ tools: tools,
13
+ max_iter: 25,
14
+ max_rpm: 10
15
+ )
16
+ end
17
+
18
+ def role
19
+ "<%= @agent_name.humanize %> Specialist"
20
+ end
21
+
22
+ def goal
23
+ "Perform <%= @agent_name.humanize.downcase %> tasks efficiently and accurately"
24
+ end
25
+
26
+ def backstory
27
+ <<~BACKSTORY
28
+ You are a highly skilled <%= @agent_name.humanize.downcase %> specialist with extensive experience.
29
+ Your expertise allows you to handle complex <%= @agent_name.humanize.downcase %> challenges effectively.
30
+ BACKSTORY
31
+ end
32
+
33
+ def tools
34
+ [
35
+ # Add your tools here
36
+ # RcrewAI::Tools::WebSearch.new,
37
+ # RcrewAI::Tools::FileReader.new,
38
+ # CustomTool.new
39
+ ]
40
+ end
41
+
42
+ def to_agent
43
+ @agent
44
+ end
45
+ end