rcrewai-rails 0.1.1 → 0.2.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 (34) 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. data/rcrewai-rails.gemspec +20 -2
  33. metadata +41 -5
  34. /data/lib/{rcrewai-rails.rb → rcrewai_rails.rb} +0 -0
@@ -0,0 +1,82 @@
1
+ <div class="page-header">
2
+ <h1>
3
+ Tasks
4
+ <% if @crew %>
5
+ for <%= link_to @crew.name, @crew %>
6
+ <% end %>
7
+ </h1>
8
+ <div class="actions">
9
+ <%= link_to "New Task", new_task_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="tasks-list">
17
+ <% if @tasks.any? %>
18
+ <% @tasks.each do |task| %>
19
+ <div class="task-card">
20
+ <div class="task-header">
21
+ <h3><%= link_to "Task ##{task.id}", task %></h3>
22
+ <div class="task-meta">
23
+ <% if task.crew %>
24
+ <span class="badge">Crew: <%= link_to task.crew.name, task.crew %></span>
25
+ <% end %>
26
+ <% if task.agent %>
27
+ <span class="badge">Agent: <%= link_to task.agent.name, task.agent %></span>
28
+ <% end %>
29
+ <% if task.async_execution %>
30
+ <span class="badge badge-info">Async</span>
31
+ <% end %>
32
+ <% unless task.active %>
33
+ <span class="badge badge-warning">Inactive</span>
34
+ <% end %>
35
+ </div>
36
+ </div>
37
+
38
+ <div class="task-content">
39
+ <div class="task-description">
40
+ <strong>Description:</strong>
41
+ <p><%= truncate(task.description, length: 200) %></p>
42
+ </div>
43
+
44
+ <div class="task-output">
45
+ <strong>Expected Output:</strong>
46
+ <p><%= truncate(task.expected_output, length: 150) %></p>
47
+ </div>
48
+ </div>
49
+
50
+ <div class="task-dependencies">
51
+ <% if task.dependencies.any? %>
52
+ <strong>Dependencies:</strong>
53
+ <div class="dependency-list">
54
+ <% task.dependencies.each do |dep| %>
55
+ <span class="dependency-badge">
56
+ <%= link_to "Task ##{dep.id}", dep %>
57
+ </span>
58
+ <% end %>
59
+ </div>
60
+ <% end %>
61
+ </div>
62
+
63
+ <div class="task-actions">
64
+ <%= link_to "View", task, class: "btn btn-sm" %>
65
+ <%= link_to "Edit", edit_task_path(task), class: "btn btn-sm" %>
66
+ </div>
67
+ </div>
68
+ <% end %>
69
+ <% else %>
70
+ <div class="empty-state">
71
+ <h3>No tasks found</h3>
72
+ <p>
73
+ <% if @crew %>
74
+ This crew doesn't have any tasks yet.
75
+ <% else %>
76
+ No tasks have been created yet.
77
+ <% end %>
78
+ </p>
79
+ <%= link_to "Create First Task", new_task_path(@crew), class: "btn btn-primary" %>
80
+ </div>
81
+ <% end %>
82
+ </div>
@@ -0,0 +1,101 @@
1
+ <div class="page-header">
2
+ <h1>New Task</h1>
3
+ <div class="actions">
4
+ <% if @task.crew %>
5
+ <%= link_to "Back to Crew", @task.crew, class: "btn" %>
6
+ <% else %>
7
+ <%= link_to "All Tasks", tasks_path, class: "btn" %>
8
+ <% end %>
9
+ </div>
10
+ </div>
11
+
12
+ <div class="form-container">
13
+ <%= form_with model: [@crew, @task].compact, local: true do |form| %>
14
+ <% if @task.errors.any? %>
15
+ <div class="alert alert-error">
16
+ <h4><%= pluralize(@task.errors.count, "error") %> prohibited this task from being saved:</h4>
17
+ <ul>
18
+ <% @task.errors.full_messages.each do |message| %>
19
+ <li><%= message %></li>
20
+ <% end %>
21
+ </ul>
22
+ </div>
23
+ <% end %>
24
+
25
+ <div class="form-group">
26
+ <%= form.label :description, class: "form-label" %>
27
+ <%= form.text_area :description, class: "form-input", rows: 4, required: true %>
28
+ <span class="form-help">Detailed description of what this task should accomplish</span>
29
+ </div>
30
+
31
+ <div class="form-group">
32
+ <%= form.label :expected_output, class: "form-label" %>
33
+ <%= form.text_area :expected_output, class: "form-input", rows: 3, required: true %>
34
+ <span class="form-help">Description of the expected output from this task</span>
35
+ </div>
36
+
37
+ <% unless @crew %>
38
+ <div class="form-group">
39
+ <%= form.label :crew_id, "Crew", class: "form-label" %>
40
+ <%= form.select :crew_id,
41
+ options_from_collection_for_select(RcrewAI::Rails::Crew.all, :id, :name, @task.crew_id),
42
+ { prompt: 'Select a crew (optional)' },
43
+ { class: "form-select" } %>
44
+ </div>
45
+ <% end %>
46
+
47
+ <div class="form-group">
48
+ <%= form.label :agent_id, "Assigned Agent", class: "form-label" %>
49
+ <% agents = @crew ? @crew.agents : RcrewAI::Rails::Agent.all %>
50
+ <%= form.select :agent_id,
51
+ options_from_collection_for_select(agents, :id, :name, @task.agent_id),
52
+ { prompt: 'Select an agent' },
53
+ { class: "form-select" } %>
54
+ </div>
55
+
56
+ <div class="form-group">
57
+ <%= form.label :async_execution, class: "form-label" %>
58
+ <%= form.check_box :async_execution, class: "form-checkbox" %>
59
+ <span class="form-help">Execute this task asynchronously</span>
60
+ </div>
61
+
62
+ <div class="form-group">
63
+ <%= form.label :order_index, "Execution Order", class: "form-label" %>
64
+ <%= form.number_field :order_index, class: "form-input", min: 0 %>
65
+ <span class="form-help">Order in which this task should be executed (0 = first)</span>
66
+ </div>
67
+
68
+ <div class="form-group">
69
+ <%= form.label :output_file, class: "form-label" %>
70
+ <%= form.text_field :output_file, class: "form-input" %>
71
+ <span class="form-help">File path where output should be saved (optional)</span>
72
+ </div>
73
+
74
+ <div class="form-group">
75
+ <%= form.label :context, class: "form-label" %>
76
+ <%= form.text_area :context, class: "form-input", rows: 3 %>
77
+ <span class="form-help">Additional context for the task (optional)</span>
78
+ </div>
79
+
80
+ <div class="form-group">
81
+ <%= form.label :config, "Configuration (JSON)", class: "form-label" %>
82
+ <%= form.text_area :config, class: "form-input", rows: 3 %>
83
+ <span class="form-help">Task configuration in JSON format (optional)</span>
84
+ </div>
85
+
86
+ <div class="form-group">
87
+ <%= form.label :tools_config, "Tools Configuration (JSON)", class: "form-label" %>
88
+ <%= form.text_area :tools_config, class: "form-input", rows: 3 %>
89
+ <span class="form-help">Tools configuration in JSON format (optional)</span>
90
+ </div>
91
+
92
+ <div class="form-actions">
93
+ <%= form.submit "Create Task", class: "btn btn-primary" %>
94
+ <% if @crew %>
95
+ <%= link_to "Cancel", @crew, class: "btn btn-secondary" %>
96
+ <% else %>
97
+ <%= link_to "Cancel", tasks_path, class: "btn btn-secondary" %>
98
+ <% end %>
99
+ </div>
100
+ <% end %>
101
+ </div>
@@ -0,0 +1,129 @@
1
+ <div class="page-header">
2
+ <h1>Task #<%= @task.id %></h1>
3
+ <div class="actions">
4
+ <%= link_to "Edit Task", edit_task_path(@task), class: "btn btn-primary" %>
5
+ <% if @task.crew %>
6
+ <%= link_to "Back to Crew", @task.crew, class: "btn" %>
7
+ <% else %>
8
+ <%= link_to "All Tasks", tasks_path, class: "btn" %>
9
+ <% end %>
10
+ </div>
11
+ </div>
12
+
13
+ <div class="task-details">
14
+ <div class="details-grid">
15
+ <div class="detail-section">
16
+ <h3>Task Information</h3>
17
+ <div class="detail-item">
18
+ <strong>Description:</strong>
19
+ <p><%= @task.description %></p>
20
+ </div>
21
+ <div class="detail-item">
22
+ <strong>Expected Output:</strong>
23
+ <p><%= @task.expected_output %></p>
24
+ </div>
25
+ <% if @task.crew %>
26
+ <div class="detail-item">
27
+ <strong>Crew:</strong> <%= link_to @task.crew.name, @task.crew %>
28
+ </div>
29
+ <% end %>
30
+ <% if @task.agent %>
31
+ <div class="detail-item">
32
+ <strong>Assigned Agent:</strong> <%= link_to @task.agent.name, @task.agent %>
33
+ </div>
34
+ <% end %>
35
+ <% if @task.output_file %>
36
+ <div class="detail-item">
37
+ <strong>Output File:</strong> <%= @task.output_file %>
38
+ </div>
39
+ <% end %>
40
+ </div>
41
+
42
+ <div class="detail-section">
43
+ <h3>Configuration</h3>
44
+ <div class="detail-item">
45
+ <strong>Status:</strong>
46
+ <span class="badge <%= @task.active ? 'badge-success' : 'badge-warning' %>">
47
+ <%= @task.active ? 'Active' : 'Inactive' %>
48
+ </span>
49
+ </div>
50
+ <div class="detail-item">
51
+ <strong>Async Execution:</strong>
52
+ <span class="badge <%= @task.async_execution ? 'badge-info' : 'badge-secondary' %>">
53
+ <%= @task.async_execution ? 'Enabled' : 'Disabled' %>
54
+ </span>
55
+ </div>
56
+ <div class="detail-item">
57
+ <strong>Order Index:</strong> <%= @task.order_index || 'Not set' %>
58
+ </div>
59
+ </div>
60
+ </div>
61
+
62
+ <% if @task.context.present? %>
63
+ <div class="detail-section">
64
+ <h3>Context</h3>
65
+ <pre class="code-block"><%= @task.context %></pre>
66
+ </div>
67
+ <% end %>
68
+
69
+ <% if @task.config.present? %>
70
+ <div class="detail-section">
71
+ <h3>Configuration</h3>
72
+ <pre class="code-block"><%= JSON.pretty_generate(@task.config) %></pre>
73
+ </div>
74
+ <% end %>
75
+
76
+ <% if @task.tools_config.present? %>
77
+ <div class="detail-section">
78
+ <h3>Tools Configuration</h3>
79
+ <pre class="code-block"><%= JSON.pretty_generate(@task.tools_config) %></pre>
80
+ </div>
81
+ <% end %>
82
+ </div>
83
+
84
+ <div class="related-sections">
85
+ <div class="section">
86
+ <div class="section-header">
87
+ <h2>Dependencies (<%= @dependencies.count %>)</h2>
88
+ </div>
89
+
90
+ <% if @dependencies.any? %>
91
+ <div class="dependencies-list">
92
+ <% @dependencies.each do |dependency| %>
93
+ <div class="dependency-item">
94
+ <h4><%= link_to "Task ##{dependency.id}", dependency %></h4>
95
+ <p><%= truncate(dependency.description, length: 100) %></p>
96
+ <div class="dependency-actions">
97
+ <%= link_to "Remove", remove_dependency_task_path(@task, dependency_id: dependency.id),
98
+ method: :delete, class: "btn btn-sm btn-danger",
99
+ confirm: "Remove this dependency?" %>
100
+ </div>
101
+ </div>
102
+ <% end %>
103
+ </div>
104
+ <% else %>
105
+ <p>This task has no dependencies.</p>
106
+ <% end %>
107
+
108
+ <div class="add-dependency">
109
+ <h4>Add Dependency</h4>
110
+ <%= form_tag add_dependency_task_path(@task), method: :post do %>
111
+ <%= select_tag :dependency_id,
112
+ options_from_collection_for_select(
113
+ RcrewAI::Rails::Task.where.not(id: [@task.id] + @task.dependencies.pluck(:id)),
114
+ :id,
115
+ ->(task) { "Task ##{task.id}: #{truncate(task.description, length: 50)}" }
116
+ ),
117
+ { prompt: 'Select a task to add as dependency' },
118
+ { class: "form-select" } %>
119
+ <%= submit_tag "Add Dependency", class: "btn btn-sm btn-primary" %>
120
+ <% end %>
121
+ </div>
122
+ </div>
123
+ </div>
124
+
125
+ <div class="danger-zone">
126
+ <%= link_to "Delete Task", @task, method: :delete,
127
+ confirm: "Are you sure you want to delete this task? This action cannot be undone.",
128
+ class: "btn btn-danger" %>
129
+ </div>
@@ -0,0 +1,60 @@
1
+ <div class="page-header">
2
+ <h1>Edit Tool: <%= @tool.name %></h1>
3
+ <div class="actions">
4
+ <%= link_to "View Tool", [@agent, @tool], class: "btn" %>
5
+ <%= link_to "Back to Agent", @agent, class: "btn" %>
6
+ </div>
7
+ </div>
8
+
9
+ <div class="form-container">
10
+ <%= form_with model: [@agent, @tool], local: true do |form| %>
11
+ <% if @tool.errors.any? %>
12
+ <div class="alert alert-error">
13
+ <h4><%= pluralize(@tool.errors.count, "error") %> prohibited this tool from being saved:</h4>
14
+ <ul>
15
+ <% @tool.errors.full_messages.each do |message| %>
16
+ <li><%= message %></li>
17
+ <% end %>
18
+ </ul>
19
+ </div>
20
+ <% end %>
21
+
22
+ <div class="form-group">
23
+ <%= form.label :name, class: "form-label" %>
24
+ <%= form.text_field :name, class: "form-input", required: true %>
25
+ <span class="form-help">Name of the tool</span>
26
+ </div>
27
+
28
+ <div class="form-group">
29
+ <%= form.label :description, class: "form-label" %>
30
+ <%= form.text_area :description, class: "form-input", rows: 3, required: true %>
31
+ <span class="form-help">Description of what this tool does</span>
32
+ </div>
33
+
34
+ <div class="form-group">
35
+ <%= form.label :tool_class, "Tool Class", class: "form-label" %>
36
+ <%= form.text_field :tool_class, class: "form-input", required: true %>
37
+ <span class="form-help">The class name of the tool implementation</span>
38
+ </div>
39
+
40
+ <div class="form-group">
41
+ <%= form.label :config, "Configuration (JSON)", class: "form-label" %>
42
+ <%= form.text_area :config, class: "form-input", rows: 5 %>
43
+ <span class="form-help">Tool configuration in JSON format (optional)</span>
44
+ </div>
45
+
46
+ <div class="form-group">
47
+ <%= form.label :active, class: "form-label" %>
48
+ <%= form.check_box :active, class: "form-checkbox" %>
49
+ <span class="form-help">Tool is active and available for use</span>
50
+ </div>
51
+
52
+ <div class="form-actions">
53
+ <%= form.submit "Update Tool", class: "btn btn-primary" %>
54
+ <%= link_to "Cancel", [@agent, @tool], class: "btn btn-secondary" %>
55
+ <%= link_to "Delete Tool", [@agent, @tool], method: :delete,
56
+ confirm: "Are you sure you want to delete this tool?",
57
+ class: "btn btn-danger" %>
58
+ </div>
59
+ <% end %>
60
+ </div>
@@ -0,0 +1,48 @@
1
+ <div class="page-header">
2
+ <h1>Tools for <%= link_to @agent.name, @agent %></h1>
3
+ <div class="actions">
4
+ <%= link_to "New Tool", new_agent_tool_path(@agent), class: "btn btn-primary" %>
5
+ <%= link_to "Back to Agent", @agent, class: "btn" %>
6
+ </div>
7
+ </div>
8
+
9
+ <div class="tools-grid">
10
+ <% if @tools.any? %>
11
+ <% @tools.each do |tool| %>
12
+ <div class="tool-card">
13
+ <div class="tool-header">
14
+ <h3><%= link_to tool.name, [@agent, tool] %></h3>
15
+ <span class="badge class-badge"><%= tool.tool_class %></span>
16
+ </div>
17
+
18
+ <div class="tool-info">
19
+ <div class="info-item">
20
+ <strong>Description:</strong>
21
+ <p><%= truncate(tool.description, length: 150) %></p>
22
+ </div>
23
+ </div>
24
+
25
+ <div class="tool-meta">
26
+ <% unless tool.active %>
27
+ <span class="badge badge-warning">Inactive</span>
28
+ <% else %>
29
+ <span class="badge badge-success">Active</span>
30
+ <% end %>
31
+ </div>
32
+
33
+ <div class="tool-actions">
34
+ <%= link_to "View", [@agent, tool], class: "btn btn-sm" %>
35
+ <%= link_to "Edit", edit_agent_tool_path(@agent, tool), class: "btn btn-sm" %>
36
+ <%= link_to "Delete", [@agent, tool], method: :delete,
37
+ confirm: "Are you sure?", class: "btn btn-sm btn-danger" %>
38
+ </div>
39
+ </div>
40
+ <% end %>
41
+ <% else %>
42
+ <div class="empty-state">
43
+ <h3>No tools found</h3>
44
+ <p>This agent doesn't have any tools configured yet.</p>
45
+ <%= link_to "Add First Tool", new_agent_tool_path(@agent), class: "btn btn-primary" %>
46
+ </div>
47
+ <% end %>
48
+ </div>
@@ -0,0 +1,56 @@
1
+ <div class="page-header">
2
+ <h1>New Tool for <%= link_to @agent.name, @agent %></h1>
3
+ <div class="actions">
4
+ <%= link_to "Back to Agent", @agent, class: "btn" %>
5
+ </div>
6
+ </div>
7
+
8
+ <div class="form-container">
9
+ <%= form_with model: [@agent, @tool], local: true do |form| %>
10
+ <% if @tool.errors.any? %>
11
+ <div class="alert alert-error">
12
+ <h4><%= pluralize(@tool.errors.count, "error") %> prohibited this tool from being saved:</h4>
13
+ <ul>
14
+ <% @tool.errors.full_messages.each do |message| %>
15
+ <li><%= message %></li>
16
+ <% end %>
17
+ </ul>
18
+ </div>
19
+ <% end %>
20
+
21
+ <div class="form-group">
22
+ <%= form.label :name, class: "form-label" %>
23
+ <%= form.text_field :name, class: "form-input", required: true %>
24
+ <span class="form-help">Name of the tool</span>
25
+ </div>
26
+
27
+ <div class="form-group">
28
+ <%= form.label :description, class: "form-label" %>
29
+ <%= form.text_area :description, class: "form-input", rows: 3, required: true %>
30
+ <span class="form-help">Description of what this tool does</span>
31
+ </div>
32
+
33
+ <div class="form-group">
34
+ <%= form.label :tool_class, "Tool Class", class: "form-label" %>
35
+ <%= form.text_field :tool_class, class: "form-input", required: true %>
36
+ <span class="form-help">The class name of the tool implementation</span>
37
+ </div>
38
+
39
+ <div class="form-group">
40
+ <%= form.label :config, "Configuration (JSON)", class: "form-label" %>
41
+ <%= form.text_area :config, class: "form-input", rows: 5 %>
42
+ <span class="form-help">Tool configuration in JSON format (optional)</span>
43
+ </div>
44
+
45
+ <div class="form-group">
46
+ <%= form.label :active, class: "form-label" %>
47
+ <%= form.check_box :active, class: "form-checkbox", checked: true %>
48
+ <span class="form-help">Tool is active and available for use</span>
49
+ </div>
50
+
51
+ <div class="form-actions">
52
+ <%= form.submit "Create Tool", class: "btn btn-primary" %>
53
+ <%= link_to "Cancel", @agent, class: "btn btn-secondary" %>
54
+ </div>
55
+ <% end %>
56
+ </div>
@@ -0,0 +1,47 @@
1
+ <div class="page-header">
2
+ <h1><%= @tool.name %></h1>
3
+ <div class="actions">
4
+ <%= link_to "Edit Tool", edit_agent_tool_path(@agent, @tool), class: "btn btn-primary" %>
5
+ <%= link_to "Back to Agent", @agent, class: "btn" %>
6
+ </div>
7
+ </div>
8
+
9
+ <div class="tool-details">
10
+ <div class="details-grid">
11
+ <div class="detail-section">
12
+ <h3>Tool Information</h3>
13
+ <div class="detail-item">
14
+ <strong>Name:</strong> <%= @tool.name %>
15
+ </div>
16
+ <div class="detail-item">
17
+ <strong>Description:</strong>
18
+ <p><%= @tool.description %></p>
19
+ </div>
20
+ <div class="detail-item">
21
+ <strong>Tool Class:</strong> <%= @tool.tool_class %>
22
+ </div>
23
+ <div class="detail-item">
24
+ <strong>Agent:</strong> <%= link_to @agent.name, @agent %>
25
+ </div>
26
+ <div class="detail-item">
27
+ <strong>Status:</strong>
28
+ <span class="badge <%= @tool.active ? 'badge-success' : 'badge-warning' %>">
29
+ <%= @tool.active ? 'Active' : 'Inactive' %>
30
+ </span>
31
+ </div>
32
+ </div>
33
+ </div>
34
+
35
+ <% if @tool.config.present? %>
36
+ <div class="detail-section">
37
+ <h3>Configuration</h3>
38
+ <pre class="code-block"><%= JSON.pretty_generate(@tool.config) %></pre>
39
+ </div>
40
+ <% end %>
41
+ </div>
42
+
43
+ <div class="danger-zone">
44
+ <%= link_to "Delete Tool", [@agent, @tool], method: :delete,
45
+ confirm: "Are you sure you want to delete this tool? This action cannot be undone.",
46
+ class: "btn btn-danger" %>
47
+ </div>
@@ -0,0 +1,25 @@
1
+ class AddAgentToTasks < ActiveRecord::Migration[7.0]
2
+ def change
3
+ add_reference :rcrewai_tasks, :agent, null: true, foreign_key: { to_table: :rcrewai_agents }
4
+ add_column :rcrewai_tasks, :active, :boolean, default: true
5
+ add_column :rcrewai_tasks, :order_index, :integer, default: 0
6
+
7
+ add_index :rcrewai_tasks, :agent_id
8
+ add_index :rcrewai_tasks, :active
9
+
10
+ # Create tools table
11
+ create_table :rcrewai_tools do |t|
12
+ t.references :agent, null: false, foreign_key: { to_table: :rcrewai_agents }
13
+ t.string :name, null: false
14
+ t.text :description
15
+ t.string :tool_class, null: false
16
+ t.text :config
17
+ t.boolean :active, default: true
18
+
19
+ t.timestamps
20
+ end
21
+
22
+ add_index :rcrewai_tools, :agent_id
23
+ add_index :rcrewai_tools, :active
24
+ end
25
+ end
@@ -2,6 +2,22 @@ module RcrewAI
2
2
  module Rails
3
3
  class Engine < ::Rails::Engine
4
4
  isolate_namespace RcrewAI::Rails
5
+
6
+ # Fix inflector for RcrewAI constant
7
+ ActiveSupport::Inflector.inflections(:en) do |inflect|
8
+ inflect.acronym 'AI'
9
+ inflect.acronym 'RcrewAI'
10
+ end
11
+
12
+ config.autoload_paths += %W[
13
+ #{config.root}/app
14
+ #{config.root}/lib
15
+ ]
16
+
17
+ config.eager_load_paths += %W[
18
+ #{config.root}/app
19
+ #{config.root}/lib
20
+ ]
5
21
 
6
22
  config.generators do |g|
7
23
  g.test_framework :rspec
@@ -14,17 +30,7 @@ module RcrewAI
14
30
  app.config.assets.paths << root.join("app/assets/javascripts")
15
31
  end
16
32
 
17
- initializer "rcrewai_rails.load_models" do
18
- ActiveSupport.on_load(:active_record) do
19
- Dir[Engine.root.join("app/models/rcrewai/rails/*.rb")].each { |f| require f }
20
- end
21
- end
22
33
 
23
- initializer "rcrewai_rails.load_jobs" do
24
- ActiveSupport.on_load(:active_job) do
25
- Dir[Engine.root.join("app/jobs/rcrewai/rails/*.rb")].each { |f| require f }
26
- end
27
- end
28
34
 
29
35
  initializer "rcrewai_rails.configure" do |app|
30
36
  RcrewAI::Rails.configure do |config|
@@ -1,5 +1,5 @@
1
1
  module RcrewAI
2
2
  module Rails
3
- VERSION = "0.1.1"
3
+ VERSION = "0.2.1"
4
4
  end
5
5
  end
@@ -6,8 +6,22 @@ Gem::Specification.new do |spec|
6
6
  spec.authors = ["gkosmo"]
7
7
  spec.email = ["gkosmo1@hotmail.com"]
8
8
 
9
- spec.summary = "Rails integration for RcrewAI - AI agent orchestration framework"
10
- spec.description = "A Rails engine that provides ActiveRecord persistence, background job integration, generators, and web UI for RcrewAI crews and agents"
9
+ spec.summary = "Rails integration for RcrewAI - Build AI agent crews with database persistence and web UI"
10
+ spec.description = <<~DESC
11
+ RcrewAI Rails is a comprehensive Rails engine that brings AI agent orchestration to your Rails applications.
12
+ Build intelligent AI crews that collaborate to solve complex tasks with full database persistence,
13
+ background job integration, and a beautiful web dashboard for monitoring and management.
14
+
15
+ Features:
16
+ • ActiveRecord models for crews, agents, tasks, and executions with full persistence
17
+ • Rails generators for scaffolding AI crews and agents
18
+ • ActiveJob integration for asynchronous crew execution (works with any Rails background job adapter)
19
+ • Web dashboard with real-time monitoring and management interface
20
+ • Multi-LLM support: OpenAI GPT, Anthropic Claude, Google Gemini, Azure OpenAI, Ollama
21
+ • Production-ready with logging, error handling, and security controls
22
+ • Human-in-the-loop workflows with approval mechanisms
23
+ • Tool ecosystem: web search, file operations, SQL, email, code execution
24
+ DESC
11
25
  spec.homepage = "https://github.com/gkosmo/rcrewai-rails"
12
26
  spec.license = "MIT"
13
27
  spec.required_ruby_version = ">= 3.0.0"
@@ -15,6 +29,10 @@ Gem::Specification.new do |spec|
15
29
  spec.metadata["homepage_uri"] = spec.homepage
16
30
  spec.metadata["source_code_uri"] = spec.homepage
17
31
  spec.metadata["changelog_uri"] = "#{spec.homepage}/blob/main/CHANGELOG.md"
32
+ spec.metadata["documentation_uri"] = "https://gkosmo.github.io/rcrewAI/"
33
+ spec.metadata["bug_tracker_uri"] = "#{spec.homepage}/issues"
34
+ spec.metadata["wiki_uri"] = "#{spec.homepage}/wiki"
35
+ spec.metadata["rubygems_mfa_required"] = "true"
18
36
 
19
37
  spec.files = Dir.chdir(__dir__) do
20
38
  `git ls-files -z`.split("\x0").reject do |f|