rcrewai-rails 0.1.1 → 0.2.0

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 (33) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/rcrewai/rails/agents_controller.rb +64 -0
  3. data/app/controllers/rcrewai/rails/api/v1/crews_controller.rb +55 -0
  4. data/app/controllers/rcrewai/rails/api/v1/executions_controller.rb +52 -0
  5. data/app/controllers/rcrewai/rails/crews_controller.rb +1 -1
  6. data/app/controllers/rcrewai/rails/executions_controller.rb +2 -2
  7. data/app/controllers/rcrewai/rails/tasks_controller.rb +76 -0
  8. data/app/controllers/rcrewai/rails/tools_controller.rb +61 -0
  9. data/app/models/rcrewai/rails/agent.rb +2 -2
  10. data/app/models/rcrewai/rails/task.rb +2 -6
  11. data/app/models/rcrewai/rails/tool.rb +26 -0
  12. data/app/views/rcrewai/rails/agents/edit.html.erb +107 -0
  13. data/app/views/rcrewai/rails/agents/index.html.erb +81 -0
  14. data/app/views/rcrewai/rails/agents/new.html.erb +103 -0
  15. data/app/views/rcrewai/rails/agents/show.html.erb +136 -0
  16. data/app/views/rcrewai/rails/crews/edit.html.erb +87 -0
  17. data/app/views/rcrewai/rails/crews/index.html.erb +1 -1
  18. data/app/views/rcrewai/rails/crews/new.html.erb +75 -0
  19. data/app/views/rcrewai/rails/executions/index.html.erb +91 -0
  20. data/app/views/rcrewai/rails/executions/show.html.erb +1 -1
  21. data/app/views/rcrewai/rails/tasks/edit.html.erb +105 -0
  22. data/app/views/rcrewai/rails/tasks/index.html.erb +82 -0
  23. data/app/views/rcrewai/rails/tasks/new.html.erb +101 -0
  24. data/app/views/rcrewai/rails/tasks/show.html.erb +129 -0
  25. data/app/views/rcrewai/rails/tools/edit.html.erb +60 -0
  26. data/app/views/rcrewai/rails/tools/index.html.erb +48 -0
  27. data/app/views/rcrewai/rails/tools/new.html.erb +56 -0
  28. data/app/views/rcrewai/rails/tools/show.html.erb +47 -0
  29. data/db/migrate/001_add_agent_to_tasks.rb +25 -0
  30. data/lib/rcrewai/rails/engine.rb +16 -10
  31. data/lib/rcrewai/rails/version.rb +1 -1
  32. metadata +24 -2
  33. /data/lib/{rcrewai-rails.rb → rcrewai_rails.rb} +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d07d3c8b88c4bf9326dc8fc588cc58d0b02112d8c92d4d6eccc25a3da98d58a2
4
- data.tar.gz: 1ce7c0563541bc473d6d1d3a092063d0ec86d7617d314fe733e444d37f761bfc
3
+ metadata.gz: aadb4d8abbd4b79d0a17b6e4f36e826354dd98a31d09616b8ac4c15e7c9891cb
4
+ data.tar.gz: cd7047f28d7ee5de4ff15324df7d58424cd4fb8780f2f82989dd613959260e82
5
5
  SHA512:
6
- metadata.gz: 267b55d87d5ef72a12560a689459cc82cc93e99e55200b2c6128e492d4736f3911717c07b8616cb623baf8c595398084d9f57c0375e95deaf220b6f695c8c50a
7
- data.tar.gz: 899ce8199ad7727e3bca13bf07362cf5184ba3ccc1431e35bd2564c57e91597c67db9744d9286c1caa115c9bd54cb2d7fb27fc29859d0b044d6bcd2fd6d6b034
6
+ metadata.gz: 74bbb33990e4fd0d9605560e2d8d00fb6e54bc370e04abc76e4f4a82228968eb67df81661da50b7d5d0f9f695bd0be9e8e07c3ffe2cedd8454b1123bd1e10f68
7
+ data.tar.gz: cc6fa8206ab6e5dae0b54fca6f5bf90e972815a2d18ad945e0f120578b0eb467870f9e8c781cf48eafa7684e6713bf4b51b36cbddbec62df62b96feff77d8ef2
@@ -0,0 +1,64 @@
1
+ module RcrewAI
2
+ module Rails
3
+ class AgentsController < ApplicationController
4
+ before_action :set_crew, if: -> { params[:crew_id] }
5
+ before_action :set_agent, only: [:show, :edit, :update, :destroy]
6
+
7
+ def index
8
+ @agents = @crew ? @crew.agents : Agent.includes(:crew).all
9
+ end
10
+
11
+ def show
12
+ @tools = @agent.tools
13
+ end
14
+
15
+ def new
16
+ @agent = @crew ? @crew.agents.build : Agent.new
17
+ end
18
+
19
+ def create
20
+ @agent = @crew ? @crew.agents.build(agent_params) : Agent.new(agent_params)
21
+
22
+ if @agent.save
23
+ redirect_to @agent, notice: 'Agent was successfully created.'
24
+ else
25
+ render :new
26
+ end
27
+ end
28
+
29
+ def edit
30
+ end
31
+
32
+ def update
33
+ if @agent.update(agent_params)
34
+ redirect_to @agent, notice: 'Agent was successfully updated.'
35
+ else
36
+ render :edit
37
+ end
38
+ end
39
+
40
+ def destroy
41
+ crew = @agent.crew
42
+ @agent.destroy
43
+ redirect_to crew ? crew : agents_url, notice: 'Agent was successfully deleted.'
44
+ end
45
+
46
+ private
47
+
48
+ def set_crew
49
+ @crew = Crew.find(params[:crew_id])
50
+ end
51
+
52
+ def set_agent
53
+ @agent = @crew ? @crew.agents.find(params[:id]) : Agent.find(params[:id])
54
+ end
55
+
56
+ def agent_params
57
+ params.require(:agent).permit(
58
+ :name, :role, :goal, :backstory, :verbose, :allow_delegation,
59
+ :max_iter, :max_execution_time, :llm_config, :tools_config, :active
60
+ )
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,55 @@
1
+ module RcrewAI
2
+ module Rails
3
+ module Api
4
+ module V1
5
+ class CrewsController < ApplicationController
6
+ skip_before_action :check_web_ui_enabled
7
+ before_action :set_crew, only: [:show, :execute]
8
+
9
+ def index
10
+ @crews = Crew.includes(:agents, :tasks).all
11
+ render json: @crews.as_json(include: [:agents, :tasks])
12
+ end
13
+
14
+ def show
15
+ render json: @crew.as_json(include: [:agents, :tasks, :executions])
16
+ end
17
+
18
+ def create
19
+ @crew = Crew.new(crew_params)
20
+
21
+ if @crew.save
22
+ render json: @crew, status: :created
23
+ else
24
+ render json: { errors: @crew.errors }, status: :unprocessable_entity
25
+ end
26
+ end
27
+
28
+ def execute
29
+ inputs = params[:inputs] || {}
30
+ execution = @crew.execute_async(inputs)
31
+
32
+ render json: {
33
+ execution_id: execution.id,
34
+ status: execution.status,
35
+ message: 'Crew execution started successfully'
36
+ }
37
+ end
38
+
39
+ private
40
+
41
+ def set_crew
42
+ @crew = Crew.find(params[:id])
43
+ end
44
+
45
+ def crew_params
46
+ params.require(:crew).permit(
47
+ :name, :description, :process_type, :verbose,
48
+ :memory_enabled, :cache_enabled, :max_rpm, :manager_llm, :active
49
+ )
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,52 @@
1
+ module RcrewAI
2
+ module Rails
3
+ module Api
4
+ module V1
5
+ class ExecutionsController < ApplicationController
6
+ skip_before_action :check_web_ui_enabled
7
+ before_action :set_execution, only: [:show, :status, :logs]
8
+
9
+ def index
10
+ @executions = Execution.includes(:crew)
11
+ @executions = @executions.where(crew_id: params[:crew_id]) if params[:crew_id]
12
+ @executions = @executions.where(status: params[:status]) if params[:status]
13
+ @executions = @executions.recent.limit(params[:limit] || 50)
14
+
15
+ render json: @executions.as_json(include: :crew)
16
+ end
17
+
18
+ def show
19
+ render json: @execution.as_json(
20
+ include: :crew,
21
+ methods: [:duration_seconds]
22
+ )
23
+ end
24
+
25
+ def status
26
+ render json: {
27
+ id: @execution.id,
28
+ status: @execution.status,
29
+ started_at: @execution.started_at,
30
+ completed_at: @execution.completed_at,
31
+ duration_seconds: @execution.duration_seconds
32
+ }
33
+ end
34
+
35
+ def logs
36
+ @logs = @execution.execution_logs
37
+ @logs = @logs.where(level: params[:level]) if params[:level]
38
+ @logs = @logs.recent.limit(params[:limit] || 100)
39
+
40
+ render json: @logs.as_json(only: [:id, :level, :message, :details, :timestamp])
41
+ end
42
+
43
+ private
44
+
45
+ def set_execution
46
+ @execution = Execution.find(params[:id])
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -4,7 +4,7 @@ module RcrewAI
4
4
  before_action :set_crew, only: [:show, :edit, :update, :destroy, :execute]
5
5
 
6
6
  def index
7
- @crews = Crew.includes(:agents, :tasks).page(params[:page])
7
+ @crews = Crew.includes(:agents, :tasks).all
8
8
  end
9
9
 
10
10
  def show
@@ -7,11 +7,11 @@ module RcrewAI
7
7
  @executions = Execution.includes(:crew)
8
8
  @executions = @executions.where(crew_id: params[:crew_id]) if params[:crew_id]
9
9
  @executions = @executions.where(status: params[:status]) if params[:status]
10
- @executions = @executions.recent.page(params[:page])
10
+ @executions = @executions.recent.limit(20)
11
11
  end
12
12
 
13
13
  def show
14
- @logs = @execution.execution_logs.recent.page(params[:page])
14
+ @logs = @execution.execution_logs.recent.limit(50)
15
15
 
16
16
  respond_to do |format|
17
17
  format.html
@@ -0,0 +1,76 @@
1
+ module RcrewAI
2
+ module Rails
3
+ class TasksController < ApplicationController
4
+ before_action :set_crew, if: -> { params[:crew_id] }
5
+ before_action :set_task, only: [:show, :edit, :update, :destroy, :add_dependency, :remove_dependency]
6
+
7
+ def index
8
+ @tasks = @crew ? @crew.tasks.ordered : Task.includes(:crew, :agent).ordered
9
+ end
10
+
11
+ def show
12
+ @dependencies = @task.dependencies
13
+ end
14
+
15
+ def new
16
+ @task = @crew ? @crew.tasks.build : Task.new
17
+ end
18
+
19
+ def create
20
+ @task = @crew ? @crew.tasks.build(task_params) : Task.new(task_params)
21
+
22
+ if @task.save
23
+ redirect_to @task, notice: 'Task was successfully created.'
24
+ else
25
+ render :new
26
+ end
27
+ end
28
+
29
+ def edit
30
+ end
31
+
32
+ def update
33
+ if @task.update(task_params)
34
+ redirect_to @task, notice: 'Task was successfully updated.'
35
+ else
36
+ render :edit
37
+ end
38
+ end
39
+
40
+ def destroy
41
+ crew = @task.crew
42
+ @task.destroy
43
+ redirect_to crew ? crew : tasks_url, notice: 'Task was successfully deleted.'
44
+ end
45
+
46
+ def add_dependency
47
+ dependency = Task.find(params[:dependency_id])
48
+ @task.dependencies << dependency unless @task.dependencies.include?(dependency)
49
+ redirect_to @task, notice: 'Dependency added successfully.'
50
+ end
51
+
52
+ def remove_dependency
53
+ dependency = @task.dependencies.find(params[:dependency_id])
54
+ @task.dependencies.delete(dependency)
55
+ redirect_to @task, notice: 'Dependency removed successfully.'
56
+ end
57
+
58
+ private
59
+
60
+ def set_crew
61
+ @crew = Crew.find(params[:crew_id])
62
+ end
63
+
64
+ def set_task
65
+ @task = @crew ? @crew.tasks.find(params[:id]) : Task.find(params[:id])
66
+ end
67
+
68
+ def task_params
69
+ params.require(:task).permit(
70
+ :description, :expected_output, :agent_id, :async_execution,
71
+ :context, :config, :tools_config, :output_file, :active, :order_index
72
+ )
73
+ end
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,61 @@
1
+ module RcrewAI
2
+ module Rails
3
+ class ToolsController < ApplicationController
4
+ before_action :set_agent
5
+ before_action :set_tool, only: [:show, :edit, :update, :destroy]
6
+
7
+ def index
8
+ @tools = @agent.tools
9
+ end
10
+
11
+ def show
12
+ end
13
+
14
+ def new
15
+ @tool = @agent.tools.build
16
+ end
17
+
18
+ def create
19
+ @tool = @agent.tools.build(tool_params)
20
+
21
+ if @tool.save
22
+ redirect_to [@agent, @tool], notice: 'Tool was successfully created.'
23
+ else
24
+ render :new
25
+ end
26
+ end
27
+
28
+ def edit
29
+ end
30
+
31
+ def update
32
+ if @tool.update(tool_params)
33
+ redirect_to [@agent, @tool], notice: 'Tool was successfully updated.'
34
+ else
35
+ render :edit
36
+ end
37
+ end
38
+
39
+ def destroy
40
+ @tool.destroy
41
+ redirect_to @agent, notice: 'Tool was successfully deleted.'
42
+ end
43
+
44
+ private
45
+
46
+ def set_agent
47
+ @agent = Agent.find(params[:agent_id])
48
+ end
49
+
50
+ def set_tool
51
+ @tool = @agent.tools.find(params[:id])
52
+ end
53
+
54
+ def tool_params
55
+ params.require(:tool).permit(
56
+ :name, :description, :tool_class, :config, :active
57
+ )
58
+ end
59
+ end
60
+ end
61
+ end
@@ -4,8 +4,8 @@ module RcrewAI
4
4
  self.table_name = "rcrewai_agents"
5
5
 
6
6
  belongs_to :crew
7
- has_many :task_assignments, dependent: :destroy
8
- has_many :tasks, through: :task_assignments
7
+ has_many :tasks, dependent: :nullify
8
+ has_many :tools, class_name: 'RcrewAI::Rails::Tool', dependent: :destroy
9
9
 
10
10
  validates :name, presence: true
11
11
  validates :role, presence: true
@@ -4,8 +4,7 @@ module RcrewAI
4
4
  self.table_name = "rcrewai_tasks"
5
5
 
6
6
  belongs_to :crew
7
- has_many :task_assignments, dependent: :destroy
8
- has_many :agents, through: :task_assignments
7
+ belongs_to :agent, optional: true
9
8
  has_many :task_dependencies, foreign_key: :task_id, dependent: :destroy
10
9
  has_many :dependencies, through: :task_dependencies, source: :dependency
11
10
 
@@ -17,7 +16,7 @@ module RcrewAI
17
16
  serialize :output_pydantic, coder: JSON
18
17
  serialize :tools, coder: JSON, type: Array
19
18
 
20
- scope :ordered, -> { order(position: :asc) }
19
+ scope :ordered, -> { order(:order_index) }
21
20
 
22
21
  def to_rcrew_task
23
22
  RCrewAI::Task.new(
@@ -34,9 +33,6 @@ module RcrewAI
34
33
  )
35
34
  end
36
35
 
37
- def agent
38
- agents.first
39
- end
40
36
 
41
37
  def instantiated_tools
42
38
  return [] if tools.blank?
@@ -0,0 +1,26 @@
1
+ module RcrewAI
2
+ module Rails
3
+ class Tool < ApplicationRecord
4
+ self.table_name = "rcrewai_tools"
5
+
6
+ belongs_to :agent
7
+
8
+ validates :name, presence: true
9
+ validates :tool_class, presence: true
10
+
11
+ serialize :config, coder: JSON
12
+
13
+ scope :active, -> { where(active: true) }
14
+
15
+ def instantiated_tool
16
+ return nil if tool_class.blank?
17
+
18
+ klass = tool_class.constantize
19
+ params = config || {}
20
+ klass.new(**params.symbolize_keys)
21
+ rescue NameError
22
+ nil
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,107 @@
1
+ <div class="page-header">
2
+ <h1>Edit Agent: <%= @agent.name %></h1>
3
+ <div class="actions">
4
+ <%= link_to "View Agent", @agent, class: "btn" %>
5
+ <% if @agent.crew %>
6
+ <%= link_to "Back to Crew", @agent.crew, class: "btn" %>
7
+ <% else %>
8
+ <%= link_to "All Agents", agents_path, class: "btn" %>
9
+ <% end %>
10
+ </div>
11
+ </div>
12
+
13
+ <div class="form-container">
14
+ <%= form_with model: @agent, local: true do |form| %>
15
+ <% if @agent.errors.any? %>
16
+ <div class="alert alert-error">
17
+ <h4><%= pluralize(@agent.errors.count, "error") %> prohibited this agent from being saved:</h4>
18
+ <ul>
19
+ <% @agent.errors.full_messages.each do |message| %>
20
+ <li><%= message %></li>
21
+ <% end %>
22
+ </ul>
23
+ </div>
24
+ <% end %>
25
+
26
+ <div class="form-group">
27
+ <%= form.label :name, class: "form-label" %>
28
+ <%= form.text_field :name, class: "form-input", required: true %>
29
+ </div>
30
+
31
+ <div class="form-group">
32
+ <%= form.label :role, class: "form-label" %>
33
+ <%= form.text_field :role, class: "form-input", required: true %>
34
+ <span class="form-help">The role this agent plays in the crew</span>
35
+ </div>
36
+
37
+ <div class="form-group">
38
+ <%= form.label :goal, class: "form-label" %>
39
+ <%= form.text_area :goal, class: "form-input", rows: 3, required: true %>
40
+ <span class="form-help">What this agent is trying to achieve</span>
41
+ </div>
42
+
43
+ <div class="form-group">
44
+ <%= form.label :backstory, class: "form-label" %>
45
+ <%= form.text_area :backstory, class: "form-input", rows: 4, required: true %>
46
+ <span class="form-help">The agent's background and experience</span>
47
+ </div>
48
+
49
+ <div class="form-group">
50
+ <%= form.label :crew_id, "Crew", class: "form-label" %>
51
+ <%= form.select :crew_id,
52
+ options_from_collection_for_select(RcrewAI::Rails::Crew.all, :id, :name, @agent.crew_id),
53
+ { prompt: 'Select a crew (optional)' },
54
+ { class: "form-select" } %>
55
+ </div>
56
+
57
+ <div class="form-group">
58
+ <%= form.label :verbose, class: "form-label" %>
59
+ <%= form.check_box :verbose, class: "form-checkbox" %>
60
+ <span class="form-help">Enable verbose logging for this agent</span>
61
+ </div>
62
+
63
+ <div class="form-group">
64
+ <%= form.label :allow_delegation, class: "form-label" %>
65
+ <%= form.check_box :allow_delegation, class: "form-checkbox" %>
66
+ <span class="form-help">Allow this agent to delegate tasks to other agents</span>
67
+ </div>
68
+
69
+ <div class="form-group">
70
+ <%= form.label :max_iter, "Max Iterations", class: "form-label" %>
71
+ <%= form.number_field :max_iter, class: "form-input", min: 1 %>
72
+ <span class="form-help">Maximum number of iterations (optional)</span>
73
+ </div>
74
+
75
+ <div class="form-group">
76
+ <%= form.label :max_execution_time, "Max Execution Time (seconds)", class: "form-label" %>
77
+ <%= form.number_field :max_execution_time, class: "form-input", min: 1 %>
78
+ <span class="form-help">Maximum execution time in seconds (optional)</span>
79
+ </div>
80
+
81
+ <div class="form-group">
82
+ <%= form.label :llm_config, "LLM Configuration (JSON)", class: "form-label" %>
83
+ <%= form.text_area :llm_config, class: "form-input", rows: 3 %>
84
+ <span class="form-help">LLM configuration in JSON format (optional)</span>
85
+ </div>
86
+
87
+ <div class="form-group">
88
+ <%= form.label :tools_config, "Tools Configuration (JSON)", class: "form-label" %>
89
+ <%= form.text_area :tools_config, class: "form-input", rows: 3 %>
90
+ <span class="form-help">Tools configuration in JSON format (optional)</span>
91
+ </div>
92
+
93
+ <div class="form-group">
94
+ <%= form.label :active, class: "form-label" %>
95
+ <%= form.check_box :active, class: "form-checkbox" %>
96
+ <span class="form-help">Agent is active</span>
97
+ </div>
98
+
99
+ <div class="form-actions">
100
+ <%= form.submit "Update Agent", class: "btn btn-primary" %>
101
+ <%= link_to "Cancel", @agent, class: "btn btn-secondary" %>
102
+ <%= link_to "Delete Agent", @agent, method: :delete,
103
+ confirm: "Are you sure you want to delete this agent?",
104
+ class: "btn btn-danger" %>
105
+ </div>
106
+ <% end %>
107
+ </div>
@@ -0,0 +1,81 @@
1
+ <div class="page-header">
2
+ <h1>
3
+ Agents
4
+ <% if @crew %>
5
+ for <%= link_to @crew.name, @crew %>
6
+ <% end %>
7
+ </h1>
8
+ <div class="actions">
9
+ <%= link_to "New Agent", new_agent_path(@crew), class: "btn btn-primary" %>
10
+ <% if @crew %>
11
+ <%= link_to "Back to Crew", @crew, class: "btn" %>
12
+ <% end %>
13
+ </div>
14
+ </div>
15
+
16
+ <div class="agents-grid">
17
+ <% if @agents.any? %>
18
+ <% @agents.each do |agent| %>
19
+ <div class="agent-card">
20
+ <div class="agent-header">
21
+ <h3><%= link_to agent.name, agent %></h3>
22
+ <span class="badge role-badge"><%= agent.role %></span>
23
+ </div>
24
+
25
+ <div class="agent-info">
26
+ <div class="info-item">
27
+ <strong>Goal:</strong>
28
+ <p><%= truncate(agent.goal, length: 100) %></p>
29
+ </div>
30
+
31
+ <div class="info-item">
32
+ <strong>Backstory:</strong>
33
+ <p><%= truncate(agent.backstory, length: 120) %></p>
34
+ </div>
35
+ </div>
36
+
37
+ <div class="agent-meta">
38
+ <% if agent.crew %>
39
+ <span class="badge">Crew: <%= link_to agent.crew.name, agent.crew %></span>
40
+ <% end %>
41
+ <% if agent.verbose %>
42
+ <span class="badge badge-info">Verbose</span>
43
+ <% end %>
44
+ <% if agent.allow_delegation %>
45
+ <span class="badge badge-success">Delegation</span>
46
+ <% end %>
47
+ <% unless agent.active %>
48
+ <span class="badge badge-warning">Inactive</span>
49
+ <% end %>
50
+ </div>
51
+
52
+ <div class="agent-stats">
53
+ <div class="stat">
54
+ <strong>Tools:</strong> <%= agent.tools.count %>
55
+ </div>
56
+ <div class="stat">
57
+ <strong>Tasks:</strong> <%= agent.tasks.count %>
58
+ </div>
59
+ </div>
60
+
61
+ <div class="agent-actions">
62
+ <%= link_to "View", agent, class: "btn btn-sm" %>
63
+ <%= link_to "Edit", edit_agent_path(agent), class: "btn btn-sm" %>
64
+ <%= link_to "Tools", agent_tools_path(agent), class: "btn btn-sm" %>
65
+ </div>
66
+ </div>
67
+ <% end %>
68
+ <% else %>
69
+ <div class="empty-state">
70
+ <h3>No agents found</h3>
71
+ <p>
72
+ <% if @crew %>
73
+ This crew doesn't have any agents yet.
74
+ <% else %>
75
+ No agents have been created yet.
76
+ <% end %>
77
+ </p>
78
+ <%= link_to "Create First Agent", new_agent_path(@crew), class: "btn btn-primary" %>
79
+ </div>
80
+ <% end %>
81
+ </div>